Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drawbot-skia and Django #113

Open
meyouwe opened this issue Feb 13, 2023 · 7 comments
Open

drawbot-skia and Django #113

meyouwe opened this issue Feb 13, 2023 · 7 comments

Comments

@meyouwe
Copy link

meyouwe commented Feb 13, 2023

Hey Just, this kind of left field. I have ported some drawbot code to drawbot-skia for use on a website. I use Django as my webserver. When I run the drawbot-skia code through a Django view and get it to output a skia SVG, it will output the file. Reload the page and it will output another file with a number variation. Reload again and it just keeps going. If I manually delete those files and reload the page. All the files that I have deleted are but back. Do this too quickly and you get the following warning:

drawbot_skia.errors.DrawbotError: size() can't be called if there's already a canvas active

It is odd that it is saying the canvas is still active even thought there is del canvas in the _def saveImage_svg()

I feel that this file behaviour has something to do with the FILEWStream part. Like it leaves the stream open or something. Because the underlying python-skia library is in C it is impossible for me to figure out what is going on. Outside of Django this works fine.

So I know this is a vague question but have you seen this behaviour before? Any idea why it might be doing this? Ultimately I would just like to grab the SVG and put it in the HTML page.

Talk soon, Maarten

@justvanrossum
Copy link
Owner

justvanrossum commented Feb 13, 2023

Hi Maarten, it sounds like perhaps two things:

  • Somehow you're not getting a fresh DB context when creating a new graphic
  • Perhaps Django is threaded, and (when reloading quickly) two threads access the same DB context

The solution for both could be the same.

Can you show me how you are calling drawbot-skia from your server app? Replace the actual drawing with a dummy rectangle to keep the example simple.

@meyouwe
Copy link
Author

meyouwe commented Feb 13, 2023

Hi Just. Thanks very much for getting back to me. The "not getting a fresh DB context" point you made is all I needed to fix the issue. Days of bouncing around heaps of different ideas and it was as simple as putting importlib.reload(db) in the top of function to reload the library each time.

import drawbot_skia.drawbot as db

def rect(request):
     importlib.reload(db)
     db.size(100, 100)
     db.fill(0, 1, 0)
     db.rect(0, 10, 50, 50)
     db.saveImage(f"media/rect.svg")
     return HttpResponse("<html><body>Done</body></html>")

Thank you again. Very grateful for your guidance.

@justvanrossum
Copy link
Owner

Reload the module may be effective but is not a great solution. I'll try to post a better fix later.

@meyouwe
Copy link
Author

meyouwe commented Feb 13, 2023

Actually adding db.newDrawing() also works. Would that be a better solution?

@justvanrossum
Copy link
Owner

Ah yes, newDrawing is a pretty essential thing indeed. Perhaps it's good enough, but try some stress-testing: if this code is indeed run from multiple threads, there will be hard-to-reproduce problems.

@justvanrossum
Copy link
Owner

The following example should be thread-safe:

from drawbot_skia.drawing import Drawing
# from drawbot_skia.path import BezierPath
# from math import *
# from random import randint, random

db = Drawing()
db.rect(10, 10, 200, 300)
db.saveImage("maarten_test.png")

I added some comments to show where you'd find names that are normally part of the "drawbot" namespace, but aren't part of the Drawing class.

@meyouwe
Copy link
Author

meyouwe commented Feb 14, 2023

This is great Just. Thank you very much for the hand up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants