Creating a PDF from a dependent app does not work

Hi There!

I have two apps, lets call them NO1 and NO2.

NO2 can create a PDF and works just fine.

NO1 uses NO2 as dependency and adds NO2 as component in a column panel.
NO2 works well within NO1, except when i try to print the PDF I receive the error:
ImportError: No module named Package1

NO1/NO2
https://anvil.works/build#clone:6RTS4XIZWMRBWIRA=VM47PSJWHTBHEQHB7JRZ4X5I

I think that it has to do with the fact that the path is wrong once It is used as a dependency (render_form(‘Package1.print_form’)) . I’ve tried to change it a couple times but could not get it to work.

Secondly I could imagine that my import is somehow strange, but frankly, I have no Idea how to change that.

Any Help is appreciated!

Cheers,

Mark

I had similar issues with a dependency app today…

ImportError: No module named anvil.google

or

ImportError: No module named anvil.users

So, elementary anvil modules are not found.

@Matthias for anvil dependencies like users/google you must include the service in the app itself - these can’t be imported (as far as I know) between two apps.
For the user’s service you can easily link to the same user’s table between two apps…

1 Like

@mark.breuss it seems that server modules used as a dependency only have access to the client modules/forms of the main app that’s calling them.

It works if you do .render_form('Form1')

I suspect there is a good reason for this and I can’t think of a good solution…

@stucork thanks for looking into it!

Alright, the Problem is that I have some Forms which I need to print from several different apps.
What I did now, is having copies of the Forms which i print in each app that uses them (as custom components). (For anyone that attempts this in the Future, make sure that the paths and Formnames are the same throughout your apps - otherwise this wont work)

Also creating the PDF Client Side might help, although didn’t try it since this it is not feasible with my particular case.

Thanks @stucork!
That makes totally sense. Interestingly I was not even using the user service in that server module of the dependency app. I just didn’t clean up the import statements the Anvil IDE created automatically.

So, learnings for me:

  • Always clean up your import statements (I’ll let PyCharm do this for me)
  • Move code to separate apps (that are used as dependecies) based on which Anvil service they are using
  • Hence, code that doesn’t need an Anvil service (but might be used by other apps) goes into a separate app in which no service is activated
2 Likes

Hi @mark.breuss,

Thanks for this report! We have tracked down the problem with Anvil that was causing this issue, and fixed it. The fix will go live sometime in the next 24 hours.

For reference, you should be able to pass a fully-qualified package path to render_form(), eg render_form("My_Dep_Package.Form1"), and that should work from both the main app and the dependency. (This functionality had a bug which is now fixed!)

4 Likes

Hi @meredydd,
thanks for the heads up!

Assuming the fix is already live, I think there is either still something wrong or I didn’t get the way it works now. Either way I’d appreciate the Help!

Situation:
NO2 can render a form into a pdf and download it. (either standalone or wrapped in NO1)
NO1 displays NO2 as a component.

Approach
To demonstrate my problem a simple approach with the sample apps above. The first statement succesfully prints when NO2 is “standalone”. If it fails, NO2 must be wrapped in NO1 in which case the package name is added to the path.

#Code in Server Module of NO2
from anvil.pdf import PDFRenderer
@anvil.server.callable
def create_pdf():
  try:
    pdf = PDFRenderer(page_size='A5',filename='Hi There.pdf',quality='printer',margins=0).render_form('Package1.print_form')
  except:
    pdf = PDFRenderer(page_size='A5',filename='Hi There.pdf',quality='printer',margins=0).render_form('App_NO2.Package1.print_form')
    
  return pdf

Problem
This approach does not work on NO1.
Anvil seems to automatically add the name of the app from which it is called (“App_NO1”) to the path.
image

Question
As far as I understood your post in the NO1/NO2 example, using the second pdf statement should work regardless where NO2 is opened(NO1 or by itself)?

Is this behavior intended and am I missing an Import somewhere, have a wrong path or perhaps all together?

Thanks in advance!

best, Mark