Robert
Robert

Reputation: 673

Flask: pass url path to class constructor

I am trying something probably highly unorthodox: I need to pass an argument, that comes in via the url path to the class constructor of a class-based MethodView.

http://127.0.0.1:5000/child/my_id_string

I want to pass my_id_string to the following constructor as arg1.

My most promissing try was based on this question, but I need to use class-based views instead of functions. Unfortunately the logic behind this call is somewhat more complex than the example, i.e I cannot simply refactor the code to not use "my_id" in the constructor.

from flask import Flask, request
from flask.views import MethodView

BASE = 11
app = Flask('mybase')

class Child(MethodView):
    def __init__(self, base, arg1=None):
        self.base = base
        print('some init process, where I need arg1...')

    def get(self, arg1):
        return f'Some operation with {str(arg1)}.'

app.add_url_rule(
    '/child/<arg1>',
    'child',
    view_func=Child.as_view(
        'child_view',
        BASE,
        arg1 = request.args.get('my_id')
    ),
    methods=['GET',]
)

I get the following error with the snippet as is, because I figure the registration occurs before/without a specific request, is that correct? Hope, someone is able to help. Thanks in advance!

RuntimeError: Working outside of request context.
This typically means that you attempted to use functionality that needed an active HTTP request. Consult the documentation on testing for information about how to avoid this problem.

Upvotes: 0

Views: 503

Answers (2)

TedJ
TedJ

Reputation: 31

I had the same question. My solution looked like this:

@api.doc("""Return a report by method name""")
@api.route("/reports/<method_name>")
class ReportByMethod(Reporter):
    def __init__(self, method_name):
        self.method_name = method_name
        super().__init__()

    def get(self, method_name):
        return ['method_name']

As far as my (limited) testing goes the <method_name> is passed both to the constructor and to the ReportByMethod.get() function.

Upvotes: 1

Constantine Westerink
Constantine Westerink

Reputation: 311

I am a little confused about your syntax of : app = flask("mybase") :i use app = flask(__name__)

But this is what i would do.

@app.route("/child/<arg1>")
def x(arg1):
   varArg1 = arg1
   #now you have whatever is in the url will be passed into varArg1.

Upvotes: 1

Related Questions