Skip to content

Sub directory installations not fully supported #38

@druggedhippo

Description

@druggedhippo

Issue

Subdirectory installations of OpenProject cause issues in some commands when the API generates links that contain relative URLs

https://www.openproject.org/docs/installation-and-operations/installation/docker/#2-location-subdirectory

Example

Host: www.host.com
Subdirectory: op

Full base URL is http://www.host.com/op

Links to the API look like: https://www.host.com/op/api/v3/projects?filters=[]

But in the "links" and "href" returned by API calls the links are relative to the host: "href":"/op/api/v3/projects/147/work_packages/form"

When you then try to perform certain operations such as get_project_service().find_all() it attempts to use the links href to create the context for the request ( see find_list_command.py ) and causes URL failures when it gets to the request ( get_request.py )

requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://www.host.com/op/op/api/v3/projects?filters=%5B%5D&offset=2&pageSize=20

Because it is concatenating the original base URL with the relative href link instead of the host.

My fix

Here is my fix to get_request.py

import requests
from requests.auth import HTTPBasicAuth

from pyopenproject.api_connection.request import Request

from urllib.parse import urlparse

class GetRequest(Request):

    def __init__(self, connection, context):
        super().__init__(connection, context)

    def _execute_request(self):
        with requests.Session() as s:
            s.auth = HTTPBasicAuth(self.connection.api_user, self.connection.api_key)
            s.headers.update({"Content-Type": "application/hal+json"})
            conStr = ""
            # if the self.context doesn't start with /api, then assume it's a relative url and use the hostname
            if str(self.context).startswith("/api"):
                conStr = self.connection.url_base + self.context
            else:
                o = urlparse(self.connection.url_base)
                conStr = o.scheme + "://" + o.netloc + self.context
            response = s.get(conStr)
        return response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions