We are planning to set up conan repositories for our C++ codes. We want to expose only the list of dependencies ( lib/version#user/channel) to the developers, not the logic we put in conanfile.py We are planning so, because we are creating a wrapper around conan which will have several logic and checks. This wrapper will be exposed to the users. They do not need to know the detailed logic and build steps.
Is there a way to implement the requirements ( dependency list ) outside conanfile.py, and make the list available to the users, so that they can choose which version of the library they want to use - something similar ( not same, though ) to pom.xml in maven world ?
The above answer from #amit-jaim is quite good. I would like to point a couple of further details:
It is necessary to exports the .list file, as it will be also used when the conanfile is used in the cache
The conanfile can be made a bit more pythonic
The code could be like:
from conans import ConanFile, load
class HelloConan(ConanFile):
name = "Hello"
version = "0.1"
exports = "deps.list"
def requirements(self):
for r in load("deps.list").splitlines():
self.requires(r)
If you want to be able to run conan create from directories other than the current conanfile then getting the current location of the conanfile would be necessary, something like:
def requirements(self):
f = os.path.join(os.path.dirname(__file__), "deps.list")
for r in load(f).splitlines():
self.requires(r)
I found 2 solutions :
Create a list of libraries to be used and then read that from requirements method :
localhost$ cat dependencies.list
lib1/0.0.1#user/stable
lib2/1.6.0#user/stable
lib3/1.5.0#suer/stable
Remember, there should not be any quote around the values, in the way we pass them to the self.requires() method. Now define the requirements method in conanfile.py in the following way :
def requirements(self):
try:
with open("/path/to/dependencies.list") as c:
line=c.readline()
while line:
self.requires(line)
line=c.readline()
except Exception as ex:
print(ex)
Define requirements method outside conanfile.py. Use this method if library dependency is conditional.
localhost$ cat requires.py
def requires(self):
self.requires("lib1/0.0.1#user/stable")
self.requires("lib2/2.6.0#user/stable")
if self.options.shared:
self.requires("lib3/1.5.0#user/stable")
else:
self.requires("lib3/1.5.1#user/stable")`
Then import the requires method and assign that to the requirements method in conan class, in the following way :
from conans import ConanFile, CMake, tools
from requires import requires
class HelloConan(ConanFile):
name = Hello
version = "0.0.1"
license = "LICENSE"
url = "URL"
description = "libHello, Version 0.0.1"
settings = "os", "compiler", "build_type", "arch"
....
....
Now instead of defining the requirements method with def requirements(self), do this :
requirements=requires
....
....
That's it !! conan install will get the library details, and if found in the registry, those will be installed !!
Related
We had our Airflow custom UI based on this link and it was working fine with Airflow 1.9.0.
Following this we upgraded to 1.10.1 and also enabled RBAC. Our custom UI stopped coming after this.
We followed this explanation note-on-role-based-views and tried to use our old UI templates with appbuilder_views. On the using the TestAppBuilderBaseView from /tests/plugins/test_plugin.py,
class TestAppBuilderBaseView(AppBuilderBaseView):
#expose("/")
def test(self):
return self.render("test_plugin/test.html", content="Hello galaxy!")
we get the menu and the link, but on clicking we get the error
object has no attribute 'render'
On changing this to
return self.render_template("test_plugin/test.html",content="Hello galaxy!")
we get the error
jinja2.exceptions.TemplateNotFound: test_plugin/test.html
I have tried all possible combination placing the templates folder and the html file, but still its the same error.
I do find some forums telling to enable debug on Blueprint. but I am not aware on how you can do that with Airflow
Any guidance on this please?.
Thanks in Advance
Jeenson
The version 1.10.0 when released had a bug that was not installing the plugins correctly in the new UI. This was fixed in the version 1.10.1, but the code example for plugins in Airflow documentation is broken.
I wrote a sample project to make the integration work, you can check it here: https://github.com/felipegasparini/airflow_plugin_rbac_test
But in short, you need to:
Import the BaseView from appbuilder correctly using:
from flask_appbuilder import BaseView as AppBuilderBaseView
Change the name of the method 'test' to 'list'
Set the template_folder property to point to where your templates are.
Something like this:
from airflow.plugins_manager import AirflowPlugin
from flask_appbuilder import BaseView as AppBuilderBaseView
class TestAppBuilderBaseView(AppBuilderBaseView):
template_folder = '/root/airflow/plugins/test_plugin/templates'
#expose("/")
def list(self):
return self.render_template("test.html", content="Hello galaxy!")
v_appbuilder_view = TestAppBuilderBaseView()
v_appbuilder_package = {"name": "Test View",
"category": "Test Plugin",
"view": v_appbuilder_view}
# Defining the plugin class
class AirflowTestPlugin(AirflowPlugin):
name = "test_plugin"
# operators = [PluginOperator]
# sensors = [PluginSensorOperator]
# hooks = [PluginHook]
# executors = [PluginExecutor]
# macros = [plugin_macro]
# admin_views = [v]
# flask_blueprints = [bp]
# menu_links = [ml]
appbuilder_views = [v_appbuilder_package]
# appbuilder_menu_items = [appbuilder_mitem]
I am also faced the same issue.
After including template folder in blueprint its picking up the correct folder and here is my working example.
Please keep the folder structure like below
Plugin
|_test_plugin
|_templates
|_test.html
test_plugin.py
test_plugin.py
from airflow.plugins_manager import AirflowPlugin
from flask import Blueprint
from flask_admin import BaseView, expose
from flask_admin.base import MenuLink
class TestView(BaseView):
#expose('/')
def test(self):
return self.render("test.html", content="Hello galaxy!")
v = TestView(category="Test Plugin", name="Test View")
blue_print_ = Blueprint("test_plugin",
__name__,
template_folder='templates')
class AirflowTestPlugin(AirflowPlugin):
name = "MenuLinks"
# operators = []
flask_blueprints = [blue_print_]
# hooks = []
# executors = []
admin_views = [v]
#appbuilder_views = [v_appbuilder_package]
fgasparini's answer is correct, but I also need to enable the RBAC setting
rbac = True
in airflow.cfg in order for flask_appbuilder to work with airflow, otherwise the menu won't show up.
Within a file i have several imports from the same directory. If i change the location of this file, rather than having to add one to one '../' inside import, i'd like to use a template to build them and make my life easier when it comes to change paths.
I'd like to know if i could achieve this objective with templates. This is an example of what i expect to get:
template importRoot(p: untyped) ???
importRoot a/b/c.nim # Resolves to import full/path/a/b/c.nim
importRoot a/a.nim # Resolves to import full/path/a/a.nim
You'll need a macro. For example something along the following lines:
import macros
const root = "rootfolder"
macro importRoot*(paths: varargs[untyped]): untyped =
result = newNimNode(nnkStmtList)
let sub = !root
for p in paths:
add result, quote do:
import `sub`.`p`
Note that it may be easier to simply add a --path option on the command line instead.
I'm having trouble installing django-admin_action_mail from git.
I tried to install it via:
pip install
git+https://github.com/mjbrownie/django-admin_action_mail.git
But Django did not pick it up when I added it to settings.INSTALLED_APPS.
Did I miss something?
The admin code for that app is commented out (see here: https://github.com/mjbrownie/django-admin_action_mail/blob/master/admin_action_mail/admin.py ) so nothing is going to show up on the admin page - even if it's working and enabled.
It looks as though you need to create your own models to handle the mailing functions. Take a look at the README where it tells you to add something like the following in your app's admin.py:
from admin_action_mail.actions import mail_action
class MyModelAdmin(admin.ModelAdmin):
#Note all args are optional
actions = [
mail_action(
'description' : "Send Email to Related Users",
'email_dot_path' : 'email', # dot path string to email field (eg 'user.email')
'email_template_html' : 'admin_action_email/email.html'
'reply_to' : 'noreply#example.com' # defaults to request.user.email
)
]
admin.site.register(MyModel, MyModelAdmin)
Have you added a model like that to your own app's admin.py?
EDIT: As the problem appears to be with installation, the following should help:
You can add arbitrary paths to your wsgi path spec, that means it will pick up Python app modules in other locations. Assuming your app is installed in /home/user2161049/myapp you can put your external modules under /home/user2161049/myapp/external. In this case copy the contents of that app into /home/user2161049/myapp/external/admin_action_mail/.
To add this to your settings.py:
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(SITE_ROOT, 'external'))
The first line defines SITE_ROOT based on the current running script (setup.py) at startup. The second adds the external folder into the search path. You can put anything you want in there, and even define a specific folder somewhere else if you want to keep your externals out of your app folder. Restart the server and it should find the app just fine.
I wanna get absolute path all installed_apps in "setting.py" .
app_list = [ app for app in Myproject.settings.INSTALLED_APPS ]
I list of application but how i can get absolute path all of them.
Thank you.
It's not really possible to do what you want. I mean you can get almost there, but there's no real functionality for this, and in particular, Python doesn't distinguish between classes, methods, and variables. They all count as attributes of the module.
First, INSTALLED_APPS is a tuple of strings. So, in order to get any useful information, you're going to have load them as modules:
for app in settings.INSTALLED_APPS:
module = __import__(app)
Then, once you have the actual module, you can call dir on it to get a list of its attributes:
for app in settings.INSTALLED_APPS:
module = __import__(app)
print dir(module)
And, that's about as far as you can go. It's going to output everything set in the module, not just classes. From here, about the only recourse I can think of to weed out everything but classes is to assume that naming conventions were followed and look for items that start with a capital letter. That's not exactly scientific, but that's all you got.
Today I solved my problem. I write this code and its just working. For limited name class I find name of class that inherent from "models.Model" . you can change it and enjoy that.also this code find files in depth 1 of modules. it can change.
app_list = [app for app in training.settings.INSTALLED_APPS if "task" in app]
for module in app_list:
module1 = __import__(module)
temp = module1.__path__
files_path = [temp[0] + os.sep + files_name for files_name in os.listdir(temp[0]) if
os.path.splitext(files_name)[1] == ".py"]
p = re.compile(r'class\s*\w*\s*\(models.Model\):')
for file in files_path:
infile = open(file)
text = infile.read()
all_class = p.findall(text)
print [class_name[6:][:-15] for class_name in all_class]
I'm trying to get a Hudson job to get built in a custom workspace path that is automatically generated using yyyyMMdd-HHmm. I can get the $BUILD_ID variable expanded as mentioned in bug 3997, and that seems to work fine. However, the workspace path is incorrect as it is of the format yyyy-MM-dd_HH-mm-ss. I've tried using the ZenTimestamp plugin v2.0.1, which changes the $BUILD_ID, but this only seems to take effect after the workspace is created.
Is there a method of defining a custom workspace in the manner that I want it?
You can use a groovy script to achieve that.
import hudson.model.*;
import hudson.util.*;
import java.util.*;
import java.text.*;
import java.io.*;
//Part 1 : Recover build parameter
AbstractBuild currentBuild = (AbstractBuild) Thread.currentThread().executable;
def envVars= currentBuild.properties.get("envVars");
def branchName = envVars["BRANCH_NAME"];
//Part 2 : Define new workspace Path
def newWorkspace = "C:\\Build\\"+branchName;
//Part 3 : Change current build workspace
def newWorspaceFilePath = new FilePath(new File(newWorkspace));
currentBuild.setWorkspace(newWorspaceFilePath);