Django rest framework swagger missing port when run in docker - docker

I am using rest framework swagger for the first time in my Django application. When I run it locally from PyCharm it works just fine. My app runs on port 1337 and when I Try Out my restful API endpoint and click Execute, the curl command works and the URL includes the port.
The issue is when I run my Django app in a Docker. In this case, the URL in the curl command does not include the port. Do I have to add any swagger specific configuration to my docker compose file? I have not changed my Dockerfile nor my docker-compose file at all.
What do I need to do to get this to work properly?

It seems like you have set the url parameter for the get_schema_view(...)--(DRF Doc) function. The url is used to set the canonical base URL for the schema.
If you didn't set the value, DRF will use the "requested host" as the default URL.
Ref
url = self.url
if not url and request is not None:
url = request.build_absolute_uri()
SO, you can set the url to any value or you can exclude the parameter to get the default behavior.
from rest_framework.schemas import get_schema_view
urlpatterns = [
path('openapi', get_schema_view(
title="Your Project",
description="API for all things …",
version="1.0.0"
), name='openapi-schema'),
]

Please check the file urls.py which is the place you are setting URL for SWAGGER.
Don't set url in get_schema_view function.
Also, when you are running the app by using docker, the URL in the curl command does not include the port -> That's right!
I think that your file is using multiple settings for swagger by checking like this:
if getattr(settings, "SETTINGS_ENV", None) in ["local", "dev", "draft", "production"]:

Related

How to stop Swagger UI from loading Petstore

I've been updating my company's projects to the latest versions of all the packages. When I try to run swagger (http://localhost:4000/swagger/?url=/swagger/swagger.json), it now redirects me to the Petstore.
After searching Google for an answer, it seems like I need to set the following parameter:
queryConfigEnabled=true
According to the Swagger documentation, I can set the parameter in the following ways:
Swagger UI accepts configuration parameters in four locations.
From lowest to highest precedence:
The swagger-config.yaml in the project root directory, if it exists, is baked into the application
configuration object passed as an argument to Swagger UI (SwaggerUI({ ... }))
configuration document fetched from a specified configUrl
configuration items passed as key/value pairs in the URL query string
I tried the following URL
http://localhost:4000/swagger/?queryConfigEnabled=true&url=http://localhost:4000/swagger/swagger.json
but that still redirected me to the Petstore.
I then tried to create a swagger-config.yaml file in the project root directory with the following contents:
queryConfigEnabled: "true"
url: "/swagger/swagger.json"
dom_id: "#swagger-ui"
validatorUrl: "https://validator.swagger.io/validator"
That didn't work either. I even tried to copy the config file to the project /src folder to see if that made a difference.
I tried other things like using a swagger-config.json file instead, copying the config file to the app root in the docker image, setting the configURL to point to the config file, setting the docker environment CONFIG_URL to point to the swagger config file. None of these solutions worked. I'm still being redirected to the Petstore.
As a last resort, I modified the dist/swagger-initializer.js file and added the queryConfigEnabled parameter.
That worked.
Obviously, if I delete the /node_modules folder and re-run npm install, that change will go away.
What am I doing wrong? How do I fix this?

Trouble Enabling SSL on Fuseki Server

I'm hoping some of you may be able to help me with setting up SSL on my fuseki server. I've been battling with it for a few days now and am running out of possible solutions!
OS: RHEL 8.5 (Ootpa)
Fuseki: Version 4.2.0
Currently running as system service with:
ExecStart=/home/fuseki/apache-jena-fuseki-4.2.0/fuseki-server -v -tdb2 -update -config=/home/fuseki/fuseki_data/config.ttl
This is the manual I've been working with- https://jena.apache.org/documentation/fuseki2/fuseki-data-access-control.html
The following are the provided arguments to add in the startup sequence of fuseki-server.
–https=SETUP [Name of file for certificate details.]
& –httpsPort=PORT [The port for https. Default: 3043]
The --https argument names a file in JSON which includes the name of
the certificate file and password for the certificate.
The issue is that no matter how I phrase the arguments the process returns "fuseki-server[9469]: Unknown argument: https" in the journalctl logs.
I have tried -https=dir, --https=dir, & -httpsConf=dir (where dir is the directory to my cert_details.json file).
Based on the docs https should have native support but when I check fuseki-server -help there is no mention of an https argument. I have created a .jks from my cert, have set the correct file permissions, and have allowed 3043.
I have also located the block of code in fuseki that resolves the keystore and passwd from the .json file (which led me to try using -httpsConf=)
private void setHttpsCert(String filename) {
try {
JsonObject httpsConf = JSON.read(filename);
Path path = Path.of(filename).toAbsolutePath();
String keystore = httpsConf.get("keystore").getAsString().value();
// Resolve relative to the https setup file.
this.httpsKeystore = path.getParent().resolve(keystore).toString();
this.httpsKeystorePasswd = httpsConf.get("passwd").getAsString().value();
Not sure what I'm missing here. For what it's worth I'm a chemist and I definitely don't know java all that well so it very well could be me being stupid. Any suggestions/knowledge would be greatly appreciated.
there are two ways to get HTTPS+Fuseki:
The document referred to is for the jar file here: https://repo1.maven.org/maven2/org/apache/jena/jena-fuseki-server/4.2.0/jena-fuseki-server-4.2.0.jar, not the jar in the apache-jena-fuseki download. (BTW It does not have the UI.)
The one in the apache-jena-fuseki can be use HTTPS by using a Jetty configuration using --jetty=jetty.xml (https://www.eclipse.org/jetty/documentation/current/jetty-xml-config.html) -- example: https://github.com/apache/jena/blob/main/jena-fuseki2/examples/fuseki-jetty-https.xml (which will need modifying).

Debug authentication of Bazel's http_file

I want to fetch some data in Bazel over HTTP. There's a http_file method that looks like what I want. The remote server I'm fetching from uses authentication, so I've written it as
load("#bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
http_file(
name = "data_file",
urls = ["https://example.com/data.0.1.2"],
sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
downloaded_file_path = "data_file",
)
When I try the build, I get
WARNING: Download from https://example.com/data.0.1.2 failed: class com.google.devtools.build.lib.bazel.repository.downloader.UnrecoverableHttpException GET returned 401 Unauthorized
Followed by fatal errors because the file doesn't exist.
The error makes me think that I'm not authenticating correctly. I have a .netrc file and curl is able to use it to fetch the file.
Is there a way for me to debug? If it was curl, I would pass -v and see the auth header being sent with the request. I'm not sure if bazel is failing to send any authentication or if it's incorrect.
Running Bazel 3.2.0 on Mac OS (Darwin 19.6.0) and on Linux (Ubuntu 18.04).
HTTP 401 indeed sounds like incorrectly or not at all authenticated. .netrc should be supported and recognized. If not explicitly specified with netrc attribute, ${HOME}/.netrc would be tried if HOME is in the environment and bazel runs on non-Windows host (this has been the case since bazel 1.1; and shortly in 0.29) or %USERPROFILE%/.netrc if the variable is in the environment and running on Windows (this has been the case since 3.1). At the risk of stating the obvious, the .netrc should be owned by the same UID under which the process using it runs and its permbits should be 0600. If authentication methods other then http basic are needed, auth_patterns attribute needs to be used to configure that.
I am not aware of there being any ready made repository rule debugging facility such as CLI flag, but in this case it should be viable to copy the implementation of of the rule and functions it uses from tools/build_defs/repo, instrument it to get debugging info from it and use that for the purpose. For starters perhaps just print(auth) of what auth = _get_auth(ctx, all_urls) yielded to see if the that rule got the right idea about how to talk to host in question. It should be a dict with type, login, password information for each individual urls entries. The magic itself happens in use_netrc.

How to reference embedded Docker resource files using file path URL

I have created a Docker image and embedded some static resource files within it, using the following command in the Dockerfile:
COPY resources /resources
I have a java web application running within the Docker container which requires access to these static files. File paths must be provided using a URL, E.g.:
file://c:/resources/myresourcefile.css
I am able to construct the URL programmatically but am unsure if embedded files can be referenced this way. Any guidance would be appreciated!
Note: I am specifically using the pdfreactor web service, and my Dockerfile is thus:
FROM realobjects/pdfreactor:9.1
EXPOSE 9423
COPY resources /resources
I am trying to set the "BaseURL" of the PDFreactor wrapper client to the root resource folder.
If it’s a Linux container, and the requestor is specifically your Java process running inside the container, then file:///resources will point at the directory you added (a subdirectory of the image root directory). If the URL is being served to something outside the container (like an HTML link or image reference) then a file: URL won’t be able to access files inside the container; you’d have to come up with something else to serve up the files and provide an HTTP URL to them.
As per the official doc on https://www.pdfreactor.com/product/doc_html/index.html#resourceLoading
It is also possible to specify file URLs:
Java: config.setBaseURL("file:///directory/")
PHP: $config["baseURL"] = "file:///directory/";
.NET: config.BaseURL = "file:///directory/";
CLI: --baseURL "file:///directory/"

VueJS & Webpack: ENV var unaccessible from built project

I'm working on an app with vuejs frontend and nodejs backend. My frontend makes API https requests to the backend. I've started my projet with vue-cli and webpack.
I need to get the backend API url from env variable (BACKEND_URL).
Since i'm using webpack, I added this line to config/prod.env.js :
module.exports = {
NODE_ENV: '"production"',
-> BACKEND_URL: JSON.stringify(process.env.BACKEND_URL)
}
It works flawlessly in dev mode using webpack-dev-server. I pass the env var throught docker-compose file:
environment:
- BACKEND_URL=https://whatever:3000
But when I run build, I use nginx to serve the static files (but the problem is the same using visual studio code live server extension). I send BACKEND_URL env var the same way as before. The thing is now the process.env.BACKEND_URL is undefined in the app (but defined in the container)!! So I cant make backend http calls :(
I'm struggling finding the problem, please don't be rude with the responses. Thank you
They aren not "translated" during build time, this is what is happening with you. On a node environment, when you ask for process.env it will show all environment variables available in the system, that is true. But a web application does not have access to process.env when it is executing. You need a way to translate them during build time.
To achieve that you have to use DefinePlugin. It translates anything during build time and writes a magical string where this other thing was.
Using you own example:
module.exports = {
NODE_ENV: '"production"',
BACKEND_URL: JSON.stringify(process.env.BACKEND_URL)
}
If you do this during build time, without DefinePlugin, webpack won't know what to do with it, and it is going to be a simple string.
If you use DefinePlugin:
new webpack.DefinePlugin({
"process.env.BACKEND_URL": JSON.stringify(process.env.BACKEND_URL)
});
By doing this, you are allowing webpack to translate this during build time.
Give this a shot: https://www.brandonbarnett.io/blog/2018/05/accessing-environment-variables-from-a-webpack-bundle-in-a-docker-container/
If I'm understanding your problem correctly, you're serving a webpack bundle using nginx, and trying to access an environment variable from that bundle.
Unfortunately, it doesn't quite work that way. Your JS file has no access to the environment since it's a resource that has been delivered to the client. I've proposed a solution that also delivers those env variables alongside the bundle in a separate JS file that gets created on container start.
From VueJS Docs: https://cli.vuejs.org/guide/mode-and-env.html
Using Env Variables in Client-side Code
Only variables that start with VUE_APP_ will be statically embedded into the client bundle with webpack.DefinePlugin. You can access them in your application code:
console.log(process.env.VUE_APP_SECRET)
During build, process.env.VUE_APP_SECRET will be replaced by the corresponding value. In the case of VUE_APP_SECRET=secret, it will be replaced by "secret".
So in your case, the following should do the trick. I had the same problem once in my project, which I started with vue/cli and vue create project ...
VUE_APP_BACKEND_URL=https://whatever:3000

Resources