Image not showing with a standalone bokeh server using BokehTornado instance configured with StaticFileHandler - bokeh

This is a follow up of my previous question.
The structure of the files is shown below. I have to run the scripts using python -m bokeh_module.bokeh_sub_module from the top directory. The image.png might come from an arbitrary directory later.
.
├── other_module
│ ├── __init__.py
│ └── other_sub_module.py
├── bokeh_module
│ ├── __init__.py
│ ├── image.png # not showing
│ └── bokeh_sub_module.py
└── image.png # not showing either
The bokeh_sub_module.py is using the standalone bokeh server. However the image will not show no matter where it is placed. I got this WARNING:tornado.access:404 GET /favicon.ico (::1) 0.50ms I'm not sure if this an issue from bokeh or tornado. Thank you for any help.
from other_module import other_sub_module
import os
from bokeh.server.server import Server
from bokeh.layouts import column
from bokeh.plotting import figure, show
import tornado.web
def make_document(doc):
def update():
pass
# do something with other_sub_module
p = figure(match_aspect=True)
p.image_url( ['file://image.png'], 0, 0, 1, 1)
doc.add_root(column(p, sizing_mode='stretch_both'))
doc.add_periodic_callback(callback=update, period_milliseconds=1000)
apps = {'/': make_document}
application = tornado.web.Application([(r"/(.*)", \
tornado.web.StaticFileHandler, \
{"path": os.path.dirname(__file__)}),])
server = Server(apps, tornado_app=application)
server.start()
server.io_loop.add_callback(server.show, "/")
server.io_loop.start()
I tried the argument extra_patterns and it does not work either...

You cannot use the file:// protocol with web servers and browsers. Just use regular http:// or https://. If you specify the correct URL, the StaticFileHandler should properly handle it.
Apart from that, your usage of Server is not correct. It doesn't have the tornado_app argument. Instead, pass the routes directly:
extra_patterns = [(r"/(.*)", tornado.web.StaticFileHandler,
{"path": os.path.dirname(__file__)})]
server = Server(apps, extra_patterns=extra_patterns)
BTW just in case - in general, you shouldn't serve the root of your app. Otherwise, anyone would be able to see your source code.

Related

Why does bazel's rules_foreign_cc make not find/create the artifacts?

I want to create a make rule from rules_foreign_cc.
But even the minimal example below is causing issues for me.
With the following setup:
.
├── BUILD (empty)
├── hello
│   ├── BUILD.bazel
│   ├── hello.c
│   ├── Makefile
│   └── WORKSPACE (empty)
└── WORKSPACE
WORKSPACE:
workspace(name = "test")
load("#bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_foreign_cc",
sha256 = "2a4d07cd64b0719b39a7c12218a3e507672b82a97b98c6a89d38565894cf7c51",
strip_prefix = "rules_foreign_cc-0.9.0",
url = "https://github.com/bazelbuild/rules_foreign_cc/archive/refs/tags/0.9.0.tar.gz",
)
load("#rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies")
# This sets up some common toolchains for building targets. For more details, please see
# https://bazelbuild.github.io/rules_foreign_cc/0.9.0/flatten.html#rules_foreign_cc_dependencies
rules_foreign_cc_dependencies()
local_repository(
name = "hello",
path = "hello",
)
hello/BUILD.bazel:
load("#rules_foreign_cc//foreign_cc:defs.bzl", "make")
filegroup(
name = "hellosrc",
srcs = glob([
"**",
]),
)
make(
name="hello_build",
lib_source=":hellosrc",
out_bin_dir="",
out_binaries=["hello_binary"],
targets=["all"],
)
hello/Makefile:
all:
gcc hello.c -o hello_binary
clean:
rm hello
hello/hello.c:
#include <stdio.h>
int main () {
printf("hello\n");
return 0;
}
and running
bazel build #hello//:hello_build
I'm getting
INFO: Analyzed target #hello//:hello_build (43 packages loaded, 812 targets configured).
INFO: Found 1 target...
ERROR: /home/timotheus/.cache/bazel/_bazel_timotheus/a791a0a19ff4a5d2730aa0c8954985c4/external/hello/BUILD.bazel:10:5: output 'external/hello/hello_build/hello_binary' was not created
ERROR: /home/timotheus/.cache/bazel/_bazel_timotheus/a791a0a19ff4a5d2730aa0c8954985c4/external/hello/BUILD.bazel:10:5: Foreign Cc - Make: Building hello_build failed: not all outputs were created or valid
Target #hello//:hello_build failed to build
Use --verbose_failures to see the command lines of failed build steps.
INFO: Elapsed time: 12.426s, Critical Path: 12.22s
INFO: 7 processes: 5 internal, 2 linux-sandbox.
FAILED: Build did NOT complete successfully
Basically, I have no idea where Bazel is looking for the created binaries (are they even created?). I tried to set out_bin_dir to different values or not set it at all, all with the same effect.
I expect Bazel to generate the binary and find it - or at least give me a hint what it does.
And I think I found the solution.
make of rules_foreign_cc expects that the make project has an install target.
If that's not the case, it doesn't find the binaries.
This is how I could fix my minimal example - adding an install target to the Makefile
install:
cp -rpv hello_binary $(PREFIX)

Overwriting hydra configuration groups from CLI

I am trying to overwrite from the CLI a group of parameters and I am not sure how to do it. The structure of my conf is the following
conf
├── config.yaml
├── optimizer
│ ├── adamw.yaml
│ ├── adam.yaml
│ ├── default.yaml
│ └── sgd.yaml
├── task
│ ├── default.yaml
│ └── nlp
│ ├── default_seq2seq.yaml
│ ├── summarization.yaml
│ └── text_classification.yaml
My task/default looks like this
# #package task
defaults:
- _self_
- /optimizer/adam#cfg.optimizer
_target_: src.core.task.Task
_recursive_: false
cfg:
prefix_sep: ${training.prefix_sep}
while the optimiser/default looks like this
_target_: null
lr: ${training.lr}
weight_decay: 0.001
no_decay:
- bias
- LayerNorm.weight
and one specific optimiser, say adam.yaml, looks like this
defaults:
- default
_target_: torch.optim.Adam
In the end the config I'd like to be computed is like this
task:
_target_: src.task.nlp.nli_generation.task.NLIGenerationTask
_recursive_: false
cfg:
prefix_sep: ${training.prefix_sep}
optimizer:
_target_: torch.optim.Adam
lr: ${training.lr}
weight_decay: 0.001
no_decay:
- bias
- LayerNorm.weight
I would like to be able to modify the optimiser via the CLI (say, use sgd), but I am not sure how to achieve this. I tried, but I understand why it fails, this
python train.py task.cfg.optimizer=sgd # fails
python train.py task.cfg.optimizer=/optimizer/sgd #fails
Any tips on how to achieve this?
Github discussion here.
You can't override default list entries in this form.
See this.
In particular:
CONFIG : A config to use when creating the output config. e.g. db/mysql, db/mysql#backup.
GROUP_DEFAULT : An overridable config. e.g. db: mysql, db#backup: mysql.
To be able to override a default list entry, you need to define it as a GROUP_DEFAULT.
In your case, it might look like
defaults:
- _self_
- /optimizer#cfg.optimizer: adam

Using multiple configs in the same group to interpolate values in a yaml file

In Hydra I have the following configuration:
├── conf
│ ├── config.yaml
│ ├── callbacks
│ │ ├── callback_01.yaml
│ │ └── callback_02.yaml
│ └── trainer
│ ├── default.yaml
The callbacks have a structure like this:
_target_: callback_to_instantiate
I need to pass to the trainer/default.yaml both the callbacks through interpolation.
I tried like this:
_target_: pytorch_lightning.Trainer
callbacks:
- ${callbacks.callback_01}
- ${callbacks.callback_02}
With the config.yaml like this:
defaults:
- _self_
- trainer: default
I did also other trials but it doesn't seem to work. Is there a way to interpolate like that in a yaml file by using two or more yaml files that are in the config group?
I would like if possible to keep this structure.
Currently the recommended approach is:
compose a mapping whose values are the desired callbacks, and then
use the oc.dict.values OmegaConf resolver to get a list of values from that dictionary.
# conf/config.yaml
defaults:
- callbacks#_callback_dict.cb1: callback_01
- callbacks#_callback_dict.cb2: callback_02
- trainer: default
- _self_
# conf/trainer/default.yaml
_target_: pytorch_lightning.Trainer
callbacks: ${oc.dict.values:_callback_dict}
# my_app.py
from typing import Any
import hydra
from omegaconf import DictConfig, OmegaConf
#hydra.main(config_path="conf", config_name="config")
def app(cfg: DictConfig) -> Any:
OmegaConf.resolve(cfg)
del cfg._callback_dict
print(OmegaConf.to_yaml(cfg))
if __name__ == "__main__":
app()
At the command line:
$ python my_app.py
trainer:
_target_: pytorch_lightning.Trainer
callbacks:
- _target_: callback_to_instantiate_01
- _target_: callback_to_instantiate_02
For reference, there is an open issue on Hydra's github repo advocating for an improved user experience around

A minimal fastapi example loading index.html

In my project folder I have a basic index.html file plus static files (js, css) as well as my main.py:
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from fastapi import Request
app = FastAPI()
templates = Jinja2Templates(directory="/")
app.mount("/", StaticFiles(directory="/"))
#app.get("/")
def serve_home(request: Request):
return templates.TemplateResponse("index.html", context= {"request": request})
How can I make fastapi work here? I just want my index.html and static files served on localhost.
Is it problematic not to have a static or templates folder?
Option 1: Static file mounting
It was easier than expected. Just needed to put all static files including index.html into static folder in project directory and mount static files.
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
app = FastAPI()
app.mount("/static", StaticFiles(directory="static"), name="static")
That's it. My index.html is now available under http://localhost:8000/static/index.html.
In case it should be accessible right under http://localhost:8000/ without /static and the .html ending one needs to change two things. First it needs to be mounted on / instead of /static and an HTML flag must be set to true when mounting. So just use this line instead:
app.mount("/", StaticFiles(directory="static",html = True), name="static")
(Thanks to this answer)
The index.html is now available under http://localhost:8000/
Option 2: Serving only index.html
As fastapi is based on starlette, a simple FileResponse does the job.
from starlette.responses import FileResponse
#app.get("/")
async def read_index():
return FileResponse('index.html')
Found here.
The best and most simple solution that worked for me:
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
api_app = FastAPI(title="api app")
#api_app.post("/set_influencers_to_follow")
async def set_influencers_to_follow(request):
return {}
app = FastAPI(title="main app")
app.mount("/api", api_app)
app.mount("/", StaticFiles(directory="ui", html=True), name="ui")
If project structure is like:
├── main.py
├── ui
│   ├── index.html
│   ├── style.css
│   ├── script.js

BridgeInner configuration file location

Should the bridge read the path to its certificates from bridge.conf? I think so (as explained in the doc) but when I start it, it looks for certificates in ./certificates/ folder:
[ERROR] 16:17:53+0200 [main] internal.BridgeStartup.run - Exception during bridge startup
java.nio.file.NoSuchFileException: /opt/corda/bridge/certificates/truststore.jks
Here is the block in bridge.conf:
bridgeMode = BridgeInner
outboundConfig {
artemisBrokerAddress = "myNodeServer:myNodeServerPort"
}
bridgeInnerConfig {
floatAddresses = ["floatServer:floatServerPort"]
expectedCertificateSubject = "CN=Float Local,O=Local Only,L=Paris,C=FR"
customSSLConfiguration {
keyStorePassword = "xxx"
trustStorePassword = "xxx"
sslKeystore = "./bridgecerts/bridge.jks"
trustStoreFile = "./bridgecerts/trust.jks"
crlCheckSoftFail = true
}
}
networkParametersPath = network-parameters
Below the tree :
myServerName:/opt/corda/bridge $ tree .
.
├── bridgecerts
│   ├── bridge.jks
│   └── trust.jks
├── bridge.conf
├── corda-bridgeserver-3.1.jar
├── logs
│   └── node-myServerName.log
└── network-parameters
2 directories, 6 files
Something I did wrong here ?
The weird thing is that I don't have this issue with the float on another server, set up the same way...
The bridge has two connections:
One to the float, called the tunnel connection
One to the node, called the Artemis connection
The settings in the bridgeInnerConfig block configure the tunnel connection. The exception you're seeing is for missing certificates for the Artemis connection. See the docs here:
In particular the BridgeInner setup needs a certificates folder
containing the sslkeystore.jks and truststore.jks copied from the
node and a copied network-parameters file in the workspace folder.
You need to provide the certificates folder and network-parameters file as described.
You can also configure the Artemis connection using an outboundConfig block, but it is not recommended.

Resources