I am trying to import the manager of the login route. It is in python. This is in fastapi. I am using a router so that I can seperate the main file into different pieces. I am trying to make sure that the user is logged in before he/she can see the item page. For this, I need to get the manager from the main file by importing. But, I have already imported the router from the main file, so I cannot import it back, for the system would throw a circular import error.
Here is my code:
In the router's function:
#router.get("/page/items/item/{id}", response_class=HTMLResponse)
def item_page(request: Request, id: int, db: Session = Depends(get_db), user: database_files.models.User = Depends(manager)):
cursor.execute("""SELECT * FROM ratings;""")
reviews = cursor.fetchall()
item = db.query(database_files.models.GamingItem).filter(database_files.models.GamingItem.id == id).first()
return templates.TemplateResponse("item_page_gaming.html", {"request": request, "item": item, "user": user, "reviews": reviews, "title": f"XTreme Gaming - {item.name}"})
I have to import manager, right? There is a main file already importing this so that it can include this router into its own code. So, there would be a circular import. Also, I know what you would put immediately. You would say, "don't import directly like 'from main import manager,' import like 'import main.' Then, you can put 'main.manager' in your dependency. But no, that would not work. This is because the main file is throwing an error when I do that. It says: "Error in loading ASGI app. Could not import module 'main'" I would be very happy if you can provide a solution for this- it would be a huge help to me, for this problem has been stuck with me for a while(some weeks, almost months!)
Related
I'm working at a recommendation system for Spotify and I'm using spotipy on Python. I can't use the function current_user_recently_played, because Python says that the attribute current_user_recently_played isn't valid.
I don't know how to solve this problem, I absolutely need of this information to continue with my work.
This is my code:
import spotipy
import spotipy.util as util
import json
def current_user_recently_played(self, limit=50):
return self._get('me/player/recently-played', limit=limit)
token = util.prompt_for_user_token(
username="212887#studenti.unimore.it",
scope="user-read-recently-played user-read-private user-top-read user-read-currently-playing",
client_id="xxxxxxxxxxxxxxxxxxxxxx",
client_secret="xxxxxxxxxxxxxxxxxxxxxx",
redirect_uri="https://www.google.it/")
spotify = spotipy.Spotify(auth=token)
canzonirecenti= spotify.current_user_recently_played(limit=50)
out_file = open("canzonirecenti.json","w")
out_file.write(json.dumps(canzonirecenti, sort_keys=True, indent=2))
out_file.close()
print json.dumps(canzonirecenti, sort_keys=True, indent=2)
and the response is:
AttributeError: 'Spotify' object has no attribute 'current_user_recently_played'
The Spotify API Endpoints current_user_recently_added exists in the source code on Github, but I don't seem to have it in my local installation. I think the version on the Python package index is out of date, last change to the source code was 8 months ago and last change to the PyPI version was over a year ago.
I've gotten the code example to work by patching the Spotify client object to add the method myself, but this way of doing it is not the best way generally as it adds custom behaviour to a particular instance rather than the general class.
import spotipy
import spotipy.util as util
import json
import types
def current_user_recently_played(self, limit=50):
return self._get('me/player/recently-played', limit=limit)
token = util.prompt_for_user_token(
username="xxxxxxxxxxxxxx",
scope="user-read-recently-played user-read-private user-top-read user-read-currently-playing",
client_id="xxxxxxxxxxxxxxxxxxxxxx",
client_secret="xxxxxxxxxxxxxxxxxxxxxxxx",
redirect_uri="https://www.google.it/")
spotify = spotipy.Spotify(auth=token)
spotify.current_user_recently_played = types.MethodType(current_user_recently_played, spotify)
canzonirecenti = spotify.current_user_recently_played(limit=50)
out_file = open("canzonirecenti.json","w")
out_file.write(json.dumps(canzonirecenti, sort_keys=True, indent=2))
out_file.close()
print(json.dumps(canzonirecenti, sort_keys=True, indent=2))
Other ways of getting it to work in a more correct way are:
installing it from the source on Github, instead of through Pip
poking Plamere to request he update the version on PyPI
subclass the Spotify client class and add the missing methods to the subclass (probably the quickest and simplest)
Here's a partial snippet of the way I've subclassed it in my own project:
class SpotifyConnection(spotipy.Spotify):
"""Modified version of the spotify.Spotipy class
Main changes are:
-implementing additional API endpoints (currently_playing, recently_played)
-updating the main internal call method to update the session and retry once on error,
due to an issue experienced when performing actions which require an extended time
connected.
"""
def __init__(self, client_credentials_manager, auth=None, requests_session=True, proxies=None,
requests_timeout=None):
super().__init__(auth, requests_session, client_credentials_manager, proxies, requests_timeout)
def currently_playing(self):
"""Gets whatever the authenticated user is currently listening to"""
return self._get("me/player/currently-playing")
def recently_played(self, limit=50):
"""Gets the last 50 songs the user has played
This doesn't include whatever the user is currently listening to, and no more than the
last 50 songs are available.
"""
return self._get("me/player/recently-played", limit=limit)
<...more stuff>
I have a python function in modules in web2py to send e-mails.It has the following code
message = response.render('scheduler/connectionmessage.html',cont)
I get the error
<type 'exceptions.NameError'> name 'response' is not defined"
How can I make render available in modules? The objective is to have a few such scripts under modules and execute them via scheduler from a stub under controllers.
More code -
def send_email_invites():
from gluon import *
from gluon.template import render
db = current.db
......<execute query and populate dictionary>
message = response.render('scheduler/connectionmessage.html',cont)
That is about it.
Your code already includes from gluon import *, which means you have imported the thread local current object. That object includes the response object for the current request, so you should refer to current.response rather than just response.
Note, this is not necessary in model, controller, and view files because those files are executed in a global environment that already includes the response object (along with much of the rest of the web2py API).
For more details, see http://web2py.com/books/default/chapter/29/04/the-core#Accessing-the-API-from-Python-modules.
Try this before calling response.render()
from gluon.globals import Response
response = Response()
And I know it's tempting, but try to avoid from xyz import * and be explicit.
I'm trying to learn Pyramid and having problems getting the message flash to work. I'm totally new but read the documentation and did the tutorials.
I did the tutorial on creating a wiki(tutorial here, Code here ). It worked great and was pretty easy so I decided to try to apply the flash message I saw in todo list tutorial I did(tutorial here, full code is in a single file at the bottom of the page). Basically when a todo list is created, the page is refreshed with a message saying 'New task was successfully added!'. I wanted to do that everytime someone updated a wiki article in the wiki tutorial.
So I re-read the session section in the documentaion and it says I really just need to do this:
from pyramid.session import UnencryptedCookieSessionFactoryConfig
my_session_factory = UnencryptedCookieSessionFactoryConfig('itsaseekreet')
from pyramid.config import Configurator
config = Configurator(session_factory = my_session_factory)
then in my code I need to add: request.session.flash('New wiki was successfully added!') but I get a error everytime: Pyramid error: AttributeError: No session factory registered
Here's my function(its the exact same from the tutorial except for the request.session.flash part):
#view_config(route_name='edit_page', renderer='templates/edit.pt', permission='edit')
def edit_page(request):
name = request.matchdict['pagename']
page = DBSession.query(Page).filter_by(name=name).one()
if 'form.submitted' in request.params:
page.data = request.params['body']
DBSession.add(page)
request.session.flash('page was successfully edited!')
return HTTPFound(location = request.route_url('view_page',
pagename=name))
return dict(
page=page,
save_url = request.route_url('edit_page', pagename=name),
logged_in=authenticated_userid(request),
)
(note: One thing that I think I could be doing wrong is in the todo example, all the data is in one file, but in the wiki example there are several files..I added my session imports in the view.py file because the flash message is being generated by the view itself).
What am I doing wrong? Any suggestions?
The code you provided is just an example, of course you need to apply it in a correct place. In Pyramid you should (in simple cases ;) have only 1 place in your code where you create just 1 Configurator instance, in the tutorial it is in the main function. A Configurator does not do anything by itself, except create a WSGI application with make_wsgi_app.
Thus, to add sessions there, modify wiki2/src/views/tutorial/__init__.py as follows:
from pyramid.config import Configurator
from sqlalchemy import engine_from_config
from pyramid.session import UnencryptedCookieSessionFactoryConfig
from .models import DBSession
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
my_session_factory = UnencryptedCookieSessionFactoryConfig('itsaseekreet')
config = Configurator(settings=settings, session_factory=my_session_factory)
...
My python GAE app's central application file looks like this:
import webapp2
import homepage
import user_auth
import user_confirm
import admin_user
import admin_config
import config
app = webapp2.WSGIApplication([
(user_auth.get_login_url(), user_auth.LoginHandler),
(user_auth.get_logout_url(), user_auth.LogoutHandler),
("/user/confirm", user_confirm.UserConfirmHandler),
("/admin/config", admin_config.AdminConfigHandler),
("/admin/user/add", admin_user.AdminAddUserHandler),
("/admin/user", admin_user.AdminUserHandler),
("/", homepage.HomepageHandler),
], debug=True)
As you can see, I must import a bunch of request handlers, but for each request, only one of them is used, the other imports are just useless!
That's a big waste of memory and performance because those unnecessary imports also import other things on their own. Does Google App Engine have some "caching" mechanism or something that makes these unnecessary imports negligible? I think not.
How can I avoid them? I just haven't found out the way to import 1 Request Handler per request. If I put all the routing to app.yaml, that would work the way I want, but it makes things complex because I must write app = webapp2.WSGIApplication(... for every request handler file and repeat those boring urls twice (both in the python file and in app.yaml).
Found the way here, already built into webapp2
http://webapp-improved.appspot.com/guide/routing.html#lazy-handlers
a fews days ago, i tried to learn the python twisted..
and this is how i make my webserver :
from twisted.application import internet, service
from twisted.web import static, server, script
from twisted.web.resource import Resource
import os
class NotFound(Resource):
isLeaf=True
def render(self, request):
return "Sorry... the page you're requesting is not found / forbidden"
class myStaticFile(static.File):
def directoryListing(self):
return self.childNotFound
#root=static.file(os.getcwd()+"/www")
root=myStaticFile(os.getcwd()+"/www")
root.indexNames=['index.py']
root.ignoreExt(".py")
root.processors = {'.py': script.ResourceScript}
root.childNotFound=NotFound()
application = service.Application('web')
sc = service.IServiceCollection(application)
i = internet.TCPServer(8080, server.Site(root))##UndefinedVariable
i.setServiceParent(sc)
in my code, i make an instance class for twisted.web.static.File and override the directoryListing.
so when user try to access my resource folder (http://localhost:8080/resource/ or http://localhost:8080/resource/css), it will return a notFound page.
but he can still open/read the http://localhost:8080/resource/css/style.css.
it works...
what i want to know is.. is this the correct way to do that???
is there another 'perfect' way ?
i was looking for a config that disable directoryListing like root.dirListing=False. but no luck...
Yes, that's a reasonable way to do it. You can also use twisted.web.resource.NoResource or twisted.web.resource.Forbidden instead of defining your own NotFound.