Importing functions in .py files and using them by calling function_name - module

I have a folder called Script_py, and containing a lot of .py files, for example tri_insertion.py and tri_rapide.py.
Each name.py contains just one function called also name. My aim is to :
import all the functions (and if I have to add an other .py file, it will be imported automatically),
execute one function with the command 'name(parameters)'.
I tried the solutions of How to load all modules in a folder? with a dynamic ___all___ in ___init___.py, and from Script_py import all, but a calling to a function is name.name(parameters) instead of name(parameters)

Finally the following solution works fine. Fristly, I store in a list the complete list of modules :
import os, pkgutil
test = list(module for _, module, _ in
pkgutil.iter_modules([os.path.dirname('absolute_path')]))
Secondly, I import all the modules with a for loop.
for script in test:
exec("from {module} import *".format(module=script))

Related

Python.Net: how to execute modules in packages?

I'm not a Python programmer so apologies if I don't get some of the terminology right (pacakages, modules)!
I have a folder structure that looks something like this:
C:\Test\System\
C:\Test\System\intercepts\
C:\Test\System\intercepts\utils1\
C:\Test\System\intercepts\utils2\
The last three folders each contain an empty __init__.py folder, while the latter two folders (\utils1, \utils2) contain numerous .py modules. For the purposes of my question I'm trying to execute a function within a module called "general.py" that resides in the \utils1 folder.
The first folder (C:\Test\System) contains a file called "entry.py", which imports the .py modules from all those sub-folders:
from intercepts.utils1 import general
from intercepts.utils1 import foobar
from intercepts.utils2 import ...
..etc..
And here is the C# code that executes the above module then attempts to call a function called "startup" in a module called "general.py" in the \utils1 folder:
const string EntryModule = #"C:\Test\System\entry.py";
using (Py.GIL())
{
using (var scope = Py.CreateScope())
{
var code = File.ReadAllText(EntryModule);
var scriptCompiled = PythonEngine.Compile(code, EntryModule);
scope.Execute(scriptCompiled);
dynamic func = scope.Get("general.startup");
func();
}
}
However I get a PythonException on the scope.Execute(...) line, with the following message:
No module named 'intercepts'
File "C:\Test\System\entry.py", line 1, in <module>
from intercepts.utils1 import general
I'm able to do the equivalent of this using IronPython (Python 2.7), so I assume I'm doing something wrong with Python.Net (rather than changes to how packages work in Python 3.x).
I'm using the pythonnet 3.0.0 NuGet package by the way.
Edit
I've tried importing my "entry.py" module as follows:
dynamic os = Py.Import("os");
dynamic sys = Py.Import("sys");
sys.path.append(os.path.dirname(EntryModule));
Py.Import(Path.GetFileNameWithoutExtension(EntryModule));
It now appears to get a little further, however there's a new problem:
In the "entry.py" module you can see that it first imports a module called "general", then a module called "foobar". "foobar.py" contains the line import general.
When I run my C#, the stack trace is now as follows:
No module named 'general'
File "C:\Test\System\intercepts\utils1\foobar.py", line 1, in <module>
import general
File "C:\Test\System\entry.py", line 2, in <module>
from intercepts.utils1 import foobar
Why can't the second imported module ("foobar") "see" the module that was imported immediately before it ("general")? Am I even barking up the right tree by using Py.Import() to solve my original issue?
This turned out to be a change in how Python 3 handles imports, compared to 2, and nothing to do with Python.Net.
In my "foobar.py" module I had to change import general to from . import general. The issue is explained here but I've included the pertinent section below:

Ways to import a JSON file in public folder in Vue-CLI

I want to import a JSON file to use it, I need it to modify it in the future so I put it in public folder not assets, When I refer to it like this import JSON from ../../public/Data.json it works but I don't think so after building project can be resolved because after building there is no public folder. So I tried this :
let addr = process.env.BASE_URL;
import JSON from `${addr}Data.json`;
But It throws an error : SyntaxError
I'm confused now which way is the best and is there another way ?
The assets in the public folder are copied as is to the root of the dist folder. In your code, you can reference it just as /Data.json (if your app is deployed at the root of the domain).
E.g
async someMethod() {
const baseUrl = process.env.BASE_URL;
const data = await this.someHttpClient.get(`${ baseUrl }/Data.json`);
}
If you want to import the JSON as you have tried, I suggest to put it somewhere in the src folder and import from there
E.g.
import data from '#/data/someData.json'
console.log(data);
I came across this because I was doing a stand alone SPA that I wanted to run with no DB and keep the config in a JSON file. The import statement above works great for a static conf file, but anything imported like that gets compiled with the build, so even though your someData.json will exist in the public folder you won't see any changes in your dist because it's actually reading a JS compiled file.
To get around this I:
Convert the JSON file into a simple JS variable in a conf.js file:
e.g.
var srcConf={'bGreatJSON':true};
In index.html, did
<script src='./conf.js'>
Now that the JS variable has been declared in my Vue component I can just look for the window.srcConf and assign it if it exists in mounted or created:
if(typeof window.srcConf!='undefined')
this.sConf=window.srcConf;
This also avoids the GET CORS issue that others posts I've seen runs into, even in the same directory I kept getting CORS violations trying to do an axios call to read the file.

Loading all modules in a folder

After figuring out how to achieve this in a web application using WebPack (https://medium.com/#janos.jarecsni/auto-loading-modules-c8c47472d59b) I was quite sad to see that it is impossible to do in React Native.
I think being able to load all modules in a folder is a rather key technique (this way your code does not have to know about the individual modules), and so it is rather limiting in React Native.
Anyone knows if this is possible using some arcane ways, or any ideas how to work around this?
There's a few ways to achieve this, I have written an article to discuss this in detail. The good news is that there is a Babel plugin that allows you to do this.
https://medium.com/#janos.jarecsni/auto-loading-modules-c8c47472d59b
If you want to import all the modules in the current dir, you can try this one.
import_cur_modules only imports modules in the current dir,
import_sub_modules imports all the modules including sub dirs in the current dir
Note: This function only returns the import lines that need be executed in the __init__.py in the current dir.
import_lines = import_sub_modules(os.path.dirname(__file__))
for line in import_lines:
exec(line)
import os
def import_cur_modules(base_dir: str):
"""import modules in the current dir
Note: This function only returns the import lines that need be executed in the `__init__.py` in base_dir
"""
import_lines = []
for name in os.listdir(base_dir):
if name.endswith('.py') and name != '__init__.py':
import_lines.append(f"from . import {name[:-3]}")
return import_lines
def import_sub_modules(base_dir: str):
"""import all the modules including sub dirs in the current dir
Note: This function only returns the import lines that need be executed in the `__init__.py` in base_dir
"""
import_lines = []
for root, _, files in os.walk(base_dir):
root = os.path.relpath(root, start=base_dir)
for name in files:
if name.endswith('.py') and name != '__init__.py':
path_units = os.path.join(root, name[:-3]).split('/')
if path_units[0] == '.':
path_units.pop(0)
import_lines.append(
f"from .{'.'.join(path_units[:-1])} import {path_units[-1]}"
)
return import_lines

How to use words from a named module inside another?

I'm looking for an example of how to use words exported from a named module inside another module.
From the help of import
REFINEMENTS:
/version
ver [tuple!]
Module must be this version or greater
/check
sum [binary!]
Match checksum (must be set in header)
/no-share
Force module to use its own non-shared global namespace
/no-lib
Don't export to the runtime library (lib)
/no-user
Don't export to the user context
it would suggest that import/no-lib doesn't place the imported word in the lib context, so import by itself should? But it doesn't.
This works but it seems that import by itself should work.
import/no-lib %my-named-module.reb
append lib compose [f: (:my-exported-function))
and I can then access the function by using lib/f
;in module1
word1: ...
;in module2
mod1: import 'module1
word1: :mod1/word1

Flask Blueprints: RuntimeError Application not registered on db

Ive been going at this for several hours but im afraid I still don't gronk flask app context and how my app should be implemented with Blueprints.
Ive taken a look at the this and this and have tried a few different recommendations but there must be something wrong with my basic approach.
I have one 'main' blueprint setup under the following PJ structure:
project/
app/
main/
__init__.py
routes.py
forms.py
helper.py
admin/
static/
templates/
__init__.py
models.py
app/init.py:
from flask import Flask
from config import config
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.bootstrap import Bootstrap
db = SQLAlchemy()
bootstrap = Bootstrap()
def create_app(config_version='default'):
app = Flask(__name__)
app.config.from_object(config[config_version])
bootstrap.init_app(app)
from .main import main as main_blueprint
app.register_blueprint(main_blueprint)
db.init_app(app)
return app
app/main/init.py
from flask import Blueprint
main = Blueprint('main',__name__)
from . import routes, helper
app/main/helper.py
#!/usr/bin/env python
from . import main
from ..models import SKU, Category, db
from flask import current_app
def get_categories():
cat_list = []
for cat in db.session.query(Category).all():
cat_list.append((cat.id,cat.category))
return cat_list
Everything worked fine until I created the get_categoriesfunction in helpers.py to pull a dynamic list for a select form in app/main/forms.py. When I fireup WSGI, however, I get this error:
RuntimeError: application not registered on db instance and no application bound to current context
It would appear the db referenced in helper is not associated with an app context but when I try to create one within the function, it has not worked.
What am I doing wrong and is there a better way to organize helper functions when using Blueprints?
Documentation on database contexts here here.
My first thought was that you weren't calling db.init_app(app), but was corrected in the comments.
In app/main/helper.py, you're importing the database via from ..models import SKU, Category, db. This database object will not have been initialized with the app that you've created.
The way that I've gotten around this is by having another file, a shared.py in the root directory. In that file, create the database object,
from flask.ext.sqlalchemy import SQLAlchemy
db = SQLAlchemy()
In your app/init.py, don't create a new db object. Instead, do
from shared import db
db.init_app(app)
In any place that you want to use the db object, import it from shared.py. This way, the object in the shared file will have been initialized with the app context, and there's no chance of circular imports (which is one of the problems that you can run into with having the db object outside of the app-creating file).