How to use url_for with flask_restx? - flask-restx

I can use url_for in a flask 2.0.1 template like
<!-- flask-template.html -->
<button onclick="window.location.href='{{ url_for( 'testimport') }}';" >Import</button>
along with
#app.route('/import/images')
def testimport():
return "ok"
but I cannot do it with a resource in flask-restx 0.5.1.
api = Api(app, version='1.0',
title='The Restx API',
description='An API to initiate basic operations')
ns_detect = api.namespace('detect', path='/', description='Detection')
#ns_detect.route('/detect/recording')
class DetectRecording(Resource):
def post(self):
return {"status": "ok"}
Can anybody please explain, how to correctly use url_for in the flask-restx case above?
<button value="{{ url_for( 'ns_detect.DetectRecording') }}">1</button> <!-- can't build -->
<button value="{{ Api.url_for( 'DetectRecording') }}">2</button> <!-- Api undefined -->
<button value="{{ api.url_for( 'DetectRecording') }}">3</button> <!-- api undefined -->
<button value="{{ url_for( 'ns_detect.DetectRecording') }}">4</button> <!-- can't build -->
<button value="{{ url_for( 'api.DetectRecording') }}">5</button> <!-- can't build -->
<button value="{{ url_for( 'ns_detect.DetectRecording.post') }}">6</button> <!-- can't build -->
btw: I have installed
Werkzeug 2.0.3
Jinja2 3.1.2

After some trial and error, I figured out, which magic key is required to make url_for work with flask-restx:
it's a combination of namespace and a modified classname.
Example:
ns = api.namespace('xxx', path='/', description='some description')
#ns.route('/some/endpoint')
class DoSomething(Resource):
def post(self):
return {"status": "ok"}
then use url_for({{ 'xxx_do_something' }}).
Maybe the flask-restx documentation would benefit from such an example..

When using flask.Blueprint and flask_restx.Namespace together, you have to reference the blueprint, the namespace, and the class name of the route in your call of flask.url_for.
The format, as x y described, is "blueprint.namespace_route_name". Remember that the camelcase in the class's name is deconstructed to snake_case. (RouteName -> route_name, in the example above)
Example
The example below has the API registered as a flask.Blueprint and the flask_restx.Api object registered has two namespaces (Users and Books) each with a single GET routes. Both routes return their corresponding endpoints using flask.url_for
# Create a Flask app
app = Flask(__name__)
# Create 'api' BLUEPRINT for the API, named "api"
blueprint = Blueprint('api', __name__)
# Create an instance of the Api class
api = Api(blueprint)
# Define the 'users' NAMESPACE
users_ns = Namespace('users', description='Users related operations')
# Define the 'UsersList' ROUTE in the 'users' NAMESPACE
#users_ns.route('/')
class UsersList(Resource):
def get(self):
return {'UsersList_url': url_for('api.users_users_list')}
# Define the 'books' NAMESPACE
books_ns = Namespace('books', description='Books related operations')
# Define the "Books" ROUTE in the 'books' NAMESPACE
#books_ns.route('/')
class Books(Resource):
def get(self):
return {'Books_url': url_for('api.books_books')}
# Register the namespaces with the API
api.add_namespace(users_ns)
api.add_namespace(books_ns)
# Register the blueprint with the Flask app
app.register_blueprint(blueprint)
if __name__ == '__main__':
app.run(debug=True)

Related

How to use anchors in Symfony routing?

I have defined a route as followed in my routing.yml file :
route_name:
path: "/dashboard#messages/{id}"
However when I ask Symfony to generate that route, I get :
/dashboard%23messages/12345
How can I skip the encoding part of the route generation? Or how can I escape the # char in the path definition?
PS : Working with a (big) legacy system, I cannot change the urls.
Available from Symfony 3.2.
Support for anchors has been announced for the routing component using the fragment variable :
$this->get('router')->generate('user_settings', ['_fragment' => 'password']);
Will generate an url : /user/settings#password
For more information view the announcement.
You cannot easily - route parts are encoded unconditionally:
$url = strtr(rawurlencode($url), $this->decodedChars);
see at https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Routing/Generator/UrlGenerator.php#L192
Technically you might have extended the class UrlGenerator class and swap them using router.options.generator_class parameter. Then you could override the doGenerate method and replace %23 -> #.
In twig
<a href="{{ path('user_settings', { '_fragment': 'password' }) }}">

Spock's #IgnoreIf Closure doesn't see System prop variable, set in jUnit's Suite

I Use Geb + Spock + jUnit runner + Maven
My Specs are like:
#Stepwise
class My_Spec extends GebReportingSpec {
#IgnoreIf({properties['sss'].contains('true')})
def "testFeature 1" (){
println ("--> Feature 1 runs")
given:
println ("--> mySystemProp is: ${properties['sss']}")
...
when:
...
then:
...
}
def "testFeature 2" (){
println ("--> Feature 2 runs")
when:
...
then:
...
}
}
I need to run my Specs with jUnit runner because i need to group it in TestSuites. I Found a way to set System property before testSuite run. It available in jUnit 4.9 - #ClassRule. So, i use it here.
By this way my TestSuites are like:
#RunWith(Suite.class)
#Suite.SuiteClasses([
My_Spec.class,
My_Spec1.class,
My_Spec2.class
])
class TestSuite extends Specification {
#ClassRule
public static ExternalResource testRule = new ExternalResource(){
#Override
public void before() throws Throwable{
System.setProperty('sss', 'true')
}
}
}
But #IgnoreIf behaviur doesn't work: it doesn't see added system property 'sss' however, in feature method this property is available:
when feature runs, it gives next output:
Running TestSuite
--> Feature 1 runs
--> mySystemProp is: true
--> Feature 2 runs
All this i run with maven install.
Piece of my pom.xml:
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.18.1</version>
<configuration>
<includes>
<include>TestSuite.*</include>
</includes>
<systemPropertyVariables>
What am i doing wrong?
If all is correct - How can i make it work with spock's #IgnoreIf and props, that i need to define in jUnit TestSuite?
( Please, do not offer to use jUnit's #Categories. )
Thanks.
Are you sure that properties['sss'] resolves to the right method call from within the closure passed to #IgnoreIf? I have been bitten by trying to be too groovy in the past, especially trying to use this kind of concise expressions with static imports when resolving system props in particular. Have you tried changing it to System.getProperty("sss")?
Also, the closure passed to #IfIgnore has a delegate set to org.spockframework.runtime.extension.builtin.PreconditionContext which has sys property, so you could try sys["sss"] instead. If that doesn't help then you can debug the properties available in the closure by changing your code to:
#IgnoreIf({ println sys; sys["sss"].contains("true") })

Using modules in Meteor.js with Typescript

Folks, I'm trying to do something that I thought ought to be simple, but I must be doing something wrong. I'm trying to simply have a clear structure in my meteor application which uses Typescript.
Here are my requirements:
All interfaces are available in both client and server
Some class implementations are only available on the server
I don't want to rely on file load order for my application to work properly
I need my own module to not clash with global objects (such as the Position class for example)
I need to have one monolithic include file for server, one for both client and server and one for client (don't want to have 10s of includes on top of my files)
The setup that I have right now is this
server
server-book.ts
client
shared
collections.ts
definitions
server
include.d.ts (includes all .d.ts files in this folder)
server-book.d.ts (server specific implementation of book)
client
shared
include.d.ts (includes all .d.ts files here)
book.d.ts (book interface definition)
collections.d.ts
In each .d.ts file I have
module MyModule {
interface Bla {}
};
In each .ts file that defines a class I have:
module MyModule {
export class MyBla implements Bla {};
}
All .d.ts files generated for classes are generated by tsc -d.
No .ts files are being included via ///<reference> rather only .d.ts files.
Now, when I run this, I get an error that MyModule is undefined:
/// <reference path="shared/include.d.ts"/>
/// <reference path="server/include.d.ts"/>
Meteor.startup(() => {
var temp = new MyModule.ServerBook();
});
The error occurs right on MyModule.
What am I doing wrong? What should be the proper setup here?
Thanks!
I have dealt with this issue on my blog. I decided to use the evil eval command, since it gave me the easiest possibility of using modules till something more sophisticated appears.
File /lib/foo.ts is position in the subdirectory since it has to be loaded before Bar.
eval('var Hugo = (this.Hugo || (this.Hugo = {})'); // this will override the automatically emitted var Hugo and assigns it with globally defined Hugo module
module Hugo {
export class Foo {
foo():string {
return 'foo'
}
}
}
File /bar.ts
/// <reference path="lib/foo.ts"/>
eval('var Hugo = (this.Hugo || (this.Hugo = {})'); // this will override the automatically emitted var Hugo and assigns it with globally defined Hugo module
module Hugo {
export class Bar extends Foo {
bar () : string {
return 'bar';
}
}
}
File /test.ts
/// <reference path="lib/foo.ts"/>
/// <reference path="bar.ts"/>
var m = new Hugo.Bar();
console.log(m.bar());
console.log(m.foo());
As mentioned here, for classes, the solution is even simpler:
class ExportedClass {
variable : int;
}
this.ExportedClass = ExportedClass;
Definition files should use the declare keyword. You would normally get an error if you didn't use this keyword.
declare module MyModule {
export interface Bla {}
}
And
declare module MyModule {
export class MyBla implements Bla {
}
}
It is also worth checking that the ServerBook class has the export keyword (just like MyBla in your examples).
After lot of trial and errors, here are my findings so far :
Using typescript "module" keyword doesn't get well with Meteor. I think at the moment you cannot use it (or the workarounds are too complicated for me).
However, here is what you can do :
Let say that you have package A where you want to define a class ClassToExport which you want to make public.
class ClassToExport {
getFoo(){
return "foo";
}
}
Please note that you can't write this.ClassToExport = ClassToExport and
api.export('ClassToExport') or else ClassToExport won't be available in the global scope of package A, hence the need for a module/namespace for exporting your class, which we will see next.
Now, for the class to be available for the consumers of your package, you have to create a namespace, which will be the equivalent of the "module" typescript keyword for internal module.
So let's write :
declare var packageA; //so that the compiler doesn't complain about undeclared var
packageA = packageA || {}; //so that this namespace can be reused for the entire package
packageA.ClassToExport = ClassToExport; //the actual export
Now, don't forget to write
api.export('packageA') in the package.js of package A
If you have a package B where you want to use ClassToExport, you write in package B:
var cte = new packageA.ClassToExport();
without forgetting to api.use package A in package B's package.js
If you don't want to write the namespace each time you use the class, you can also write var ClassToExport = packageA.ClassToExport; at the top of your using file.
If you need a global class for you package only, without exporting it, then you can do instead just :
this.ClassToExport = ClassToExport
and again don't write api.export('ClassToExport'), or it won't be available in the package anymore.
This way, i think the features (export/ import) of internal typescript modules are there.
If you are not afraid of gulp build, I have prepared a typescript boilerplate project which allows you to comfortably use typescript from within your app, not depending on packages.
https://github.com/tomitrescak/meteor-boilerplate-typescript
Random idea, what about extend Meteor instead of Window.
Meteor.yournamespace = Meteor.yournamespace || {};
Meteor.yournamespace.myclass = new MyClass();
or
Meteor.yournamespace.MyClass = MyClass();
I think this is less invasive than go directly to the window object IMHO. my two cents.
now you can do Meteor.yournamespace.MyClass :P
--EDIT
Then you could create a meteor-extend.d.ts file and do something like:
/// <reference path="main.d.ts" />
declare module Meteor {
var yournamespace: any;
}
Now you can remove the <any> before Meteor and Typescript will not complaint.

$firebaseSimpleLoginProvider not found

I'm having trouble getting the facebookSimpleLogin angularfire service to be dependency injected into one of my angular js services.
angular.module('cakethursdayApp')
.service('FacebookAuthService', function FacebookAuthService($firebaseSimpleLogin) {
......
});
I am getting the error "Error: [$injector:unpr] Unknown provider: $firebaseSimpleLoginProvider <- $firebaseSimpleLogin <- FacebookAuthService"
I have my scripts loaded in the following order
<script src="bower_components/firebase/firebase.js"></script>
<script src="bower_components/firebase-simple-login/firebase-simple-login.js"></script>
<script src="bower_components/angularfire/angularfire.js"></script>
Generally speaking when you have a "missing dependency" always take a look at your module declaration's dependency injection.
angular.module(modulename, [list of dependencies to inject]).
Anytime you're using firebase (with angularfire I know specifically) you'll want something like this
angular.module(modulename, ['firebase'])
Additionally (often times you'll need it) in your controller definition as well.
function myCtrl($scope, $firebase)
This way when you want to setup a reference to your firebase URL it'll look like this:
var FB = "https://##instance##.firebaseio.com/"; //your Firebase address
var ref = new Firebase(FB); // Creates a new instance of AngularFire
$scope.variableNames= $firebase(ref); // the angularfire "firebase" service reference.
(please correct me if my comments are wrong up there, this is my understanding of the code)
for use in ng-repeat or other operations
(For Example)
<div ng-repeat="variable in variableNames">
{{variable}}
</div>
You need to make two changes in current code to make it working:
angular.module('cakethursdayApp', ['firebase'])
.service('FacebookAuthService', function FacebookAuthService($firebaseAuth) {
......
});
Inject AngularFire module as dependency
Replace $firebaseSimpleLogin with $firebaseAuth because
$firebaseSimpleLogin was dropped/removed in of 0.9.0.

How to use third party api in symfony2

basically I am trying to integrate the thrid party api in symfony2 application. I have the php class from api documention. I want integrate that in my custom bundle controller.
I also looking to add the option to configure the api key and secrets. I don't know how to start. Please look at below that i want to do
Example:-
namespace Acme\DemoBundle\Controller;
class DemoController extends Controller
{
public function indexAction()
{
$myApi = new MyApi($key,$secret); // this is the stuff, I am trying to do!
return array();
}
}
First I try to create the library format symfony package. I don't know how to achive this this type. Can Some one tell me what are thinks I need to do.
TO do this in a proper way, you have to declare you api class as a service & use dependancy injection to inject your parameters :
parameters:
your_api.class: Acme\HelloBundle\Lib\YourApiClass
your_api.key: "key value for your api"
your_api.token: "token value for your api"
services:
yourApiService:
class: "%your_api.class%"
arguments: ["%your_api.key%", "%your_api.token%"]
And in your controller & many other places you'll have access like that :
$api = $this->get('yourApiService');
Take a look for more informations : http://symfony.com/doc/current/book/service_container.html
you can use it as a service:
http://symfony.com/doc/current/book/service_container.html
when i try to implement an extern api, i think about adapter pattern:
http://en.wikipedia.org/wiki/Adapter_pattern

Resources