Skip to content

Commit

Permalink
switched to axios for python backend requests and introduced XLWINGS_…
Browse files Browse the repository at this point in the history
…REQUEST_TIMEOUT
  • Loading branch information
fzumstein committed Feb 26, 2025
1 parent bde483e commit c4f7eda
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 38 deletions.
3 changes: 3 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ XLWINGS_SECRET_KEY=""
# of the environment will be shown like this: Project Name [dev]
# XLWINGS_PROJECT_NAME="xlwings Server"

# Number of seconds after which requests to the backend will timeout
# XLWINGS_REQUEST_TIMEOUT=300

# If you run the Socket.IO server in an own process, you need to configure a message
# queue, such as Redis/Valkey. E.g.: redis://host:6379/0
# XLWINGS_SOCKETIO_MESSAGE_QUEUE_URL=
Expand Down
2 changes: 2 additions & 0 deletions app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def __init__(self, **values):
manifest_id_prod: UUID4 = "4f342d85-3a49-41cb-90a5-37b1f2219040"
project_name: str = "xlwings Server"
public_addin_store: Optional[bool] = None # Deprecated. Use cdn_officejs instead.
request_timeout: Optional[int] = 300 # in seconds
secret_key: Optional[str] = None
socketio_message_queue_url: Optional[str] = None
socketio_server_app: bool = False
Expand All @@ -85,6 +86,7 @@ def jsconfig(self) -> Dict:
"xlwingsVersion": self.xlwings_version,
"onLite": self.enable_lite,
"isOfficialLiteAddin": self.is_official_lite_addin,
"requestTimeout": self.request_timeout,
}


Expand Down
21 changes: 9 additions & 12 deletions app/static/js/core/custom-functions-code.js
Original file line number Diff line number Diff line change
Expand Up @@ -225,28 +225,25 @@ async function makeServerCall(body) {

await semaphore.acquire();
try {
let response = await fetch(
const response = await axios.post(
window.location.origin + "placeholder_custom_functions_call_path",
body,
{
method: "POST",
headers: headers,
body: JSON.stringify(body),
timeout: config.requestTimeout * 1000,
},
);

if (!response.ok) {
let errMsg = await response.text();
return response.data.result;
} catch (error) {
console.error(`Attempt ${attempt}: ${error.toString()}`);
if (error.response) {
const errMsg = error.response.data;
console.error(`Attempt ${attempt}: ${errMsg}`);
if (attempt === MAX_RETRIES) {
return showError(errMsg);
}
} else {
let responseData = await response.json();
return responseData.result;
}
} catch (error) {
console.error(`Attempt ${attempt}: ${error.toString()}`);
if (attempt === MAX_RETRIES) {
} else if (attempt === MAX_RETRIES) {
return showError(error.toString());
}
} finally {
Expand Down
27 changes: 15 additions & 12 deletions app/static/js/core/xlwingsjs/xlwings.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,18 +112,21 @@ export async function runPython(
throw new Error(rawData.error);
}
} else {
// API call
let response = await fetch(url, {
method: "POST",
headers: headers,
body: JSON.stringify(payload),
});
// Parse JSON response
// TODO: align error handling with xlwings Lite
if (response.status !== 200) {
throw await response.text();
} else {
rawData = await response.json();
try {
const response = await axios.post(url, payload, {
headers: headers,
timeout: config.requestTimeout * 1000,
});
rawData = response.data;
} catch (error) {
// TODO: align error handling with xlwings Lite
if (error.response) {
throw error.response.data || error.response.statusText;
} else if (error.request) {
throw "No response received from server";
} else {
throw error.message;
}
}
}
// console.log(rawData);
Expand Down
3 changes: 3 additions & 0 deletions app/static/vendor/axios/dist/axios.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions app/static/vendor/axios/dist/axios.min.js.map

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions app/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@
<script src="{{ url_for('static', path='/vendor/bootstrap/dist/js/bootstrap.bundle.min.js') }}"></script>
<script src="{{ url_for('static', path='/js/core/bootstrap-customizations.js') }}" defer></script>
{% endif %}
{# Axios #}
<script src="{{ url_for('static', path='/vendor/axios/dist/axios.min.js') }}" defer></script>
{# Examples #}
{% if settings.enable_examples %}
<script src="{{ url_for('static', path='/js/core/examples.js') }}" defer></script>
Expand Down
94 changes: 80 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"dependencies": {
"@alpinejs/csp": "3.14.8",
"@microsoft/office-js": "1.1.106",
"axios": "1.8.1",
"bootstrap": "5.3.3",
"bootstrap-xlwings": "github:xlwings/bootstrap-xlwings#5.3.3-1",
"htmx-ext-head-support": "2.0.4",
Expand Down
1 change: 1 addition & 0 deletions scripts/copy_node_modules_to_static_folder.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"@microsoft/office-js/dist",
"@microsoft/office-js/LICENSE.md",
"pyodide",
"axios/dist/axios.min.js",
]

package_names = set(
Expand Down
3 changes: 3 additions & 0 deletions tests/.env.test
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ XLWINGS_LOG_LEVEL="INFO"
# of the environment will be shown like this: Project Name [dev]
XLWINGS_PROJECT_NAME="Test Project"

# Number of seconds after which requests to the backend will timeout
XLWINGS_REQUEST_TIMEOUT=300

# If the add-in will be distributed via Microsoft's public add-in store, set this to
# true to load office.js via their CDN
XLWINGS_CDN_OFFICEJS=false
Expand Down
3 changes: 3 additions & 0 deletions tests/.env.test2
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ XLWINGS_LOG_LEVEL="INFO"
# of the environment will be shown like this: Project Name [dev]
XLWINGS_PROJECT_NAME="Test Project"

# Number of seconds after which requests to the backend will timeout
XLWINGS_REQUEST_TIMEOUT=300

# If the add-in will be distributed via Microsoft's public add-in store, set this to
# true to load office.js via their CDN
XLWINGS_CDN_OFFICEJS=false
Expand Down
3 changes: 3 additions & 0 deletions tests/.env.testlite
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,9 @@ XLWINGS_PROJECT_NAME="Test Project"
# true to load office.js via their CDN
XLWINGS_CDN_OFFICEJS=false

# Number of seconds after which requests to the backend will timeout
XLWINGS_REQUEST_TIMEOUT=300

# If you run the Socket.IO server in an own process, you need to configure a message
# queue, such as Redis/Valkey. E.g.: redis://host:6379/0
XLWINGS_SOCKETIO_MESSAGE_QUEUE_URL=
Expand Down

0 comments on commit c4f7eda

Please sign in to comment.