Multiple static folders & templates folders in flask app - python

Is it possible to have more than one static folder in flask app? I have some .css and .js files which I am using only for certain blueprint and would like to have the files in same directory as blueprint.
My app has structure like this:
app
|
| blueprints
| |
| | blueprint_1
| | |
| | | views.py
| | | __init__.py
| |
| | blueprint_2
| | |
| | | views.py
| | | __init__.py
|
| static
| |
| | css, js, etc.
And I would like to have structure like this:
app
|
| blueprints
| |
| | blueprint_1
| | |
| | | views.py
| | | __init__.py
| | | static
| | | |
| | | | certain css, js, etc
| |
| | blueprint_2
| | |
| | | views.py
| | | __init__.py
| | | static
| | | |
| | | | certain css, js, etc
|
| static
| |
| | css, js, etc.
And similar thing with templates.
While I am using .js file in template I access it with:
{{url_for('static'), filename='jsfile'}}

Okay, I figured it out.
According to docs, if the blueprint does not have a url_prefix, it is not possible to access the blueprint’s static folder.
The solution then is:
Add url_prefix to Blueprint:
some_blueprint = Blueprint('something', __name__, static_folder='static', url_prefix='/something')
and in the template we refer to our static folder as it follows:
{{url_for('something.static', filename=...)}}
It seems kinda weird to me, that url_prefix is necessary for it to work, but whatever.

Related

Pytest doesn't seem to recognize and run my tests

So the previous answer to this question doesn't seem to work for me. But I think this problem has something to do with my package references or my setup.cfg file.
I have two tests (just to start with to try and get this working) the results are:
================================ test session starts ==================================================================================================================================================================
platform win32 -- Python 3.7.10, pytest-6.1.1, py-1.9.0, pluggy-0.13.1 -- C:\Users\heasm\Anaconda3\envs\UofS\python.exe
cachedir: .pytest_cache
rootdir: C:\USask Python\geo_calcs, configfile: setup.cfg
collected 0 items
================================= warnings summary ====================================================================================================================================================================
..\..\Users\heasm\Anaconda3\envs\UofS\lib\site-packages\_pytest\config\__init__.py:1230
C:\Users\heasm\Anaconda3\envs\UofS\lib\site-packages\_pytest\config\__init__.py:1230: PytestConfigWarning: Unknown config option: collect_ignore
self._warn_or_fail_if_strict("Unknown config option: {}\n".format(key))
-- Docs: https://docs.pytest.org/en/stable/warnings.html
================================ 1 warning in 0.61s ===================================================================================================================================================================
Now my setup.cfg file is:
current_version = 0.1.0
commit = True
tag = True
[bumpversion:file:setup.py]
search = version='{current_version}'
replace = version='{new_version}'
[bumpversion:file:geo_calcs/__init__.py]
search = __version__ = '{current_version}'
replace = __version__ = '{new_version}'
[bdist_wheel]
universal = 1
[flake8]
exclude = docs
[tool:pytest]
collect_ignore = ['setup.py']
My test cases all seem to be named correctly. Here is an example:
from geo_calcs.calculations.geochem import *
#pytest.fixture
def test_get_atomic_weight():
assert get_atomic_weight(["Si","O","O"]) == 60.0843
Finally my directory structure is:
+---geo_calcs
| | .editorconfig
| | .gitignore
| | .travis.yml
| | AUTHORS.rst
| | CONTRIBUTING.rst
| | HISTORY.rst
| | LICENSE
| | Makefile
| | MANIFEST.in
| | README.rst
| | requirements_dev.txt
| | setup.cfg
| | setup.py
| | tox.ini
| +---docs
| | authors.rst
| | conf.py
| | contributing.rst
| | history.rst
| | index.rst
| | installation.rst
| | make.bat
| | Makefile
| | readme.rst
| | usage.rst
| |
| +---geo_calcs
| | | utils.py
| | | __init__.py
| | |
| | +---calculations
| | | | geochem.py
| | | | geochron.py
| | | | __init__.py
| | | |
| | +---visualizations
| | | __init__.py
| |
| \---tests
| | test_utils.py
| | __init__.py
| |
| +---calculations
| | | test_geochem.py
| | | test_geochron.py
| | | __init__.py
| |
| +---visualizations
| | | __init__.py
Does anyone have any insight?
Remove the #pytest.fixture decorator from above the test. Tests shouldn't have that, they're discovered by naming convention.
Pytest uses glob-style name patterns to collect tests, and the discovery can be customized by the options python_files, python_classes, and python_functions in the configuration file.
The default patterns are:
[pytest]
python_files=test_*.py
python_classes=Test*
python_functions=test_*

how to import a function from parent directory into test directory

I am trying to import a function from the directory in the same project. how can i do that ?
.|____project/
| |_____src/
| | |____myproject/
| | | | __init__.py
| | | |____funtion.py
| |_____test/
| | |___ testmyproject.py
| | |____data/
| | |___testdata
How can i import the the file function.py or the functions in the function.py file in my test/testmyproject.py to test the fucntions? i am not able to import the module from function.py

Stemming for Polish language using Google App Engine Python Search Api

I'm trying to use Python Search Api in Google App Engine to search through set of Polish documents and I found, that stemming feature is not working as expected.
The word "red" in English has only one form, although there are different forms of it in Polish, based on: gender, plurality and case:
Non-plural:
| | masculine | feminine | neuter |
|--------------|------------|-----------|------------|
| Nominative | czerwony | czerwona | czerwone |
| Genitive | czerwonego | czerwonej | czerwonego |
| Dative | czerwonemu | czerwonej | czerwonemu |
| Accusative | czerwony | czerwoną | czerwone |
| Instrumental | czerwonym | czerwoną | czerwonym |
| Locative | czerwonym | czerwonej | czerwonym |
| Vocative | czerwony | czerwona | czerwone |
Plural (neuter is the same as feminine):
| | masculine | feminine |
|--------------|------------|------------|
| Nominative | czerwoni | czerwone |
| Genitive | czerwonych | czerwonych |
| Dative | czerwonym | czerwonym |
| Accusative | czerwonych | czerwone |
| Instrumental | czerwonymi | czerwonymi |
| Locative | czerwonych | czerwonych |
| Vocative | czerwoni | czerwone |
As you can see there are in total 12 unique forms of "red" in Polish: 'czerwony', 'czerwonym', 'czerwonego', 'czerwonemu', 'czerwona', 'czerwoną', 'czerwonej', 'czerwone', 'czerwoni', 'czerwonymi', 'czerwonych', 'czerwonym'
What I'd expect from Google App Engine stemmer is to treat all of them as being the same (as being "red"). Let's test it by adding endpoint to the App Engine app, which does as follows:
def test_me():
forms = {'czerwony', 'czerwonym', 'czerwonego', 'czerwonemu',
'czerwona', 'czerwoną', 'czerwonej',
'czerwone', 'czerwoni', 'czerwonymi', 'czerwonych',
'czerwonym'}
# turn each form into document and insert to index
index = search.Index(name=str(uuid.uuid4()))
index.put([search.Document(language='pl',
fields=[
search.TextField(name='color', value=form, language='pl')
])
for form in forms])
missing = {}
for form in forms:
# find out what forms can we match to 'form' using ~ stemming operator
results = index.search(query="~" + form).results
matching_forms = set([doc.field('color').value for doc in results])
# and see which we missed
missing[form] = list(forms - matching_forms)
return json.dumps(missing)
It turns out there's bunch of items, which were not matched correctly:
"czerwonym": [
"czerwona",
"czerwoną",
"czerwoni",
"czerwonych",
"czerwonej",
"czerwonymi",
"czerwonemu"
],
"czerwonemu": [
"czerwona",
"czerwoną",
"czerwone",
"czerwoni",
"czerwonych",
"czerwonej",
"czerwonego",
"czerwony",
"czerwonym",
"czerwonymi"
],
...
Am I doing something wrong here? Or maybe I have wrong expectations for GAE stemmer?
Please, note that there's a open-source polish stemmer (https://github.com/morfologik/morfologik-stemming), which handles all 12 forms without any problems. This leads me to believe that my expectations for GAE stemmer are not outrageous.

RDF/SKOS concept hierarchy as Python dictionary

In Python, how do I turn RDF/SKOS taxonomy data into a dictionary that represents the concept hierarchy only?
The dictionary must have this format:
{ 'term1': [ 'term2', 'term3'], 'term3': [{'term4' : ['term5', 'term6']}, 'term6']}
I tried using RDFLib with JSON plugins, but did not get the result I want.
I'm not much of a Python user, and I haven't worked with RDFLib, but I just pulled the SKOS and vocabulary from the SKOS vocabularies page. I wasn't sure what concepts (RDFS or OWL classes) were in the vocabulary, nor what their hierarchy was, so I ran this a SPARQL query using Jena's ARQ to select classes and their subclasses. I didn't get any results. (There were classes defined of course, but none had subclasses.) Then I decided to use both the SKOS and SKOS-XL vocabularies, and to ask for properties and subproperties as well as classes and subclasses. This is the SPARQL query I used:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
SELECT ?property ?subproperty ?class ?subclass WHERE {
{ ?subclass rdfs:subClassOf ?class }
UNION
{ ?subproperty rdfs:subPropertyOf ?property }
}
ORDER BY ?class ?property
The results I got were
-------------------------------------------------------------------------------------------------------------------
| property | subproperty | class | subclass |
===================================================================================================================
| rdfs:label | skos:altLabel | | |
| rdfs:label | skos:hiddenLabel | | |
| rdfs:label | skos:prefLabel | | |
| skos:broader | skos:broadMatch | | |
| skos:broaderTransitive | skos:broader | | |
| skos:closeMatch | skos:exactMatch | | |
| skos:inScheme | skos:topConceptOf | | |
| skos:mappingRelation | skos:broadMatch | | |
| skos:mappingRelation | skos:closeMatch | | |
| skos:mappingRelation | skos:narrowMatch | | |
| skos:mappingRelation | skos:relatedMatch | | |
| skos:narrower | skos:narrowMatch | | |
| skos:narrowerTransitive | skos:narrower | | |
| skos:note | skos:changeNote | | |
| skos:note | skos:definition | | |
| skos:note | skos:editorialNote | | |
| skos:note | skos:example | | |
| skos:note | skos:historyNote | | |
| skos:note | skos:scopeNote | | |
| skos:related | skos:relatedMatch | | |
| skos:semanticRelation | skos:broaderTransitive | | |
| skos:semanticRelation | skos:mappingRelation | | |
| skos:semanticRelation | skos:narrowerTransitive | | |
| skos:semanticRelation | skos:related | | |
| | | _:b0 | <http://www.w3.org/2008/05/skos-xl#Label> |
| | | skos:Collection | skos:OrderedCollection |
-------------------------------------------------------------------------------------------------------------------
It looks like there's not much concept hierarchy in SKOS at all. Could that explain why you didn't get the results you wanted before?

Python - How to PYTHONPATH with a complex directory structure?

Consider the following file\directory structure:
project\
| django_project\
| | __init__.py
| | django_app1\
| | | __init__.py
| | | utils\
| | | | __init__.py
| | | | bar1.py
| | | | ...
| | | ...
| | django_app2\
| | | __init__.py
| | | bar2.py
| | | ...
| | ...
| scripts\
| | __init__.py
| | foo.py
| | ...
How should I use sys.path.append in foo.py so that I could use bar1.py and bar2.py?
How would the import look like?
Using relative paths would be much more desirable for portability reasons.
At the top of your foo.py script add the following:
import os, sys
PROJECT_ROOT = os.path.join(os.path.realpath(os.path.dirname(__file__)), os.pardir)
sys.path.append(PROJECT_ROOT)
# Now you can import from the django_project package
from django_project.django_app1.utils import bar1
from django_project.django_app2 import bar2
import sys
sys.path.append('/absolute/whatever/project/django_project/django_app1')
sys.path.append('/absolute/whatever/project/django_project/django_app2')
Though you need to evaluate whether you want to have both in your path -- in case there are competing module names in both. It might make sense to only have up to django_project in your path, and call django_app1/bar1.py when you need it and import django_app2.bar2.whatever when you need it.

Categories

Resources