GithubHelp home page GithubHelp logo

cgwire / gazu Goto Github PK

View Code? Open in Web Editor NEW
83.0 83.0 55.0 6.93 MB

Python Client for the Kitsu API (Zou)

Home Page: https://gazu.cg-wire.com

License: GNU Lesser General Public License v3.0

Python 99.92% Shell 0.08%

gazu's Introduction

Kitsu Docker

Docker container for Kitsu.

If you like the project, please add a star to the Kitsu repository.

It is not recommended to use this image in production. It is intended for Kitsu testing.

For this purpose, to simplify email testing, we include an email catch-all application to intercept all emails sent by Kitsu. These can be viewed in an included webmail.

Build badge

Usage

$ docker build -t cgwire/cgwire . # or sudo docker pull cgwire/cgwire
$ docker run --init -ti --rm -p 80:80 -p 1080:1080 --name cgwire cgwire/cgwire

In order to enable data persistence, use a named volume for the database and thumbnails:

$ docker run --init -ti --rm -p 80:80 -p 1080:1080 --name cgwire -v zou-storage:/var/lib/postgresql -v zou-storage:/opt/zou/previews cgwire/cgwire

To run the image as a daemon, add the -d flag:

$ docker run --init -d --rm -p 80:80 -p 1080:1080 --name cgwire cgwire/cgwire

Kitsu credentials:

URL:

Kitsu: http://127.0.0.1:80/

Internal webmail: http://127.0.0.1:1080/

Update

After updating the image, you have to update the database schema. For that run:

$ docker exec -ti cgwire sh -c "/opt/zou/env/bin/zou upgrade-db"

Docker Compose

Thanks to our community, for Docker Compose, an implementation by Mathieu Bouzard is available

About authors

This Dockerfile is written by CGWire, a company based in France. We help animation and VFX studios to collaborate better through efficient tooling.

More than 100 studios around the world use Kitsu for their projects.

Visit cg-wire.com for more information.

CGWire Logo

gazu's People

Contributors

aboellinger avatar aderemi-adesada avatar arubinu avatar bigroy avatar chameleonworkshop avatar col-one avatar emberlightvfx avatar evanbldy avatar flablog avatar frankrousseau avatar jdrese avatar jhoolmans avatar kguyaux avatar manuelrais avatar mchaptel avatar mdk-man avatar nicktiny avatar ninglesby avatar pcharmoille avatar pilou- avatar robin-vagner avatar sourcery-ai-bot avatar tokejepsen avatar tpoveda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gazu's Issues

Not getting the tasks of an asset or shot anymore

I've this task

task = gazu.client.get("data/tasks/323f103e-e440-453c-9d94-370ef534f973")

print(task)
> {u'assignees': [],
 u'assigner_id': u'356685fa-9f0b-435e-9df4-aaacbc941c35',
 u'completion_rate': 0,
 u'created_at': u'2017-12-14T14:52:15.390616',
 u'description': None,
 u'due_date': None,
 u'duration': 0,
 u'end_date': None,
 u'entity_id': u'dd51202f-aa65-4a04-a86c-cd87d20f3d7b',
 u'estimation': 0,
 u'id': u'323f103e-e440-453c-9d94-370ef534f973',
 u'name': u'main',
 u'project_id': u'6854c5c6-0c10-4049-aaf3-0e154937e705',
 u'real_start_date': None,
 u'shotgun_id': None,
 u'sort_order': None,
 u'start_date': None,
 u'task_status_id': u'1e154256-868c-4f88-b2e3-37edea4ba680',
 u'task_type_id': u'd6f1a0e3-62d9-4bc9-be44-e73b96106854',
 u'type': u'Task',
 u'updated_at': u'2017-12-15T14:46:50.061232'}

So I can see that the related entity id is dd51202f-aa65-4a04-a86c-cd87d20f3d7b, which is an asset as I can check doing :

asset = gazu.asset.get_asset(task['entity_id'])
print(asset['name'])
> 'AG10_Souffleur3-Qf'

If I try to get the tasks of that asset (and I know at least one exists) :

gazu.task.all_for_asset(asset)
> []

It's not providing anything.
It was working some days ago. So might be a change somewhere ?

Error when trying to get a preview for a task

getting errors (tested from 0.8.0 to 0.8.6) from kitsu docker (seems latest, got fresh pull half hour ago 22oct 9am)

all_tasks = gazu.user.all_tasks_to_do()
for task in all_tasks:
    print task["entity_name"]," - ", task["task_type_name"]
    prevs = gazu.files.get_all_preview_files_for_task(task)
    print len(prevs)
    print prevs
    for preview in prevs:
        print preview
        path = "thumbs/target.png"
        gazu.files.download_preview_file_thumbnail(preview, path)

this piece of code yields error below

Traceback (most recent call last):
    gazu.files.download_preview_file_thumbnail(preview, path)
  File "/Users/des/Library/Python/2.7/lib/python/site-packages/gazu/files.py", line 1115, in download_preview_file_thumbnail
    client=client
  File "/Users/des/Library/Python/2.7/lib/python/site-packages/gazu/client.py", line 404, in download
    stream=True
AttributeError: __exit__

greenlet.greenlet size changed error on DB upgrade

I'm trying to update gazu but when I'm running DB_PASSWORD=yourdbpassword zou upgrade_db I'm getting this error:

/usr/lib/python3.7/importlib/_bootstrap.py:219: RuntimeWarning: greenlet.greenlet size changed, may indicate binary incompatibility. Expected 72 from C header, got 76 from PyObject
return f(*args, **kwds)
/usr/lib/python3.7/importlib/_bootstrap.py:219: RuntimeWarning: greenlet.greenlet size changed, may indicate binary incompatibility. Expected 72 from C header, got 76 from PyObject
return f(*args, **kwds)
/usr/lib/python3.7/importlib/_bootstrap.py:219: RuntimeWarning: greenlet.greenlet size changed, may indicate binary incompatibility. Expected 72 from C header, got 76 from PyObject
return f(*args, **kwds)
/usr/lib/python3.7/importlib/_bootstrap.py:219: RuntimeWarning: greenlet.greenlet size changed, may indicate binary incompatibility. Expected 72 from C header, got 76 from PyObject
return f(*args, **kwds)
/usr/lib/python3.7/importlib/_bootstrap.py:219: RuntimeWarning: greenlet.greenlet size changed, may indicate binary incompatibility. Expected 72 from C header, got 76 from PyObject
return f(*args, **kwds)
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.

I had to downgrade greenlet from 0.4.17 to 0.4.13 gevent from 1.4.0 to 1.3.4 (because greenlet 0.4.13 couldn't use 1.4.0).
After doing this I could sucessfully update my database.

Creating a shot raise an error

When i create a shot with
gazu.shot.new_shot(project,sequence,name)
the shot is created without any trouble.
But when i try this :
gazu.shot.new_shot(project,sequence,name,frame_in=10,frame_out=100)
Gazu raise : ValueError: Circular reference detected

Error while starting with gazu python

Error while starting with gazu python:

import gazu
gazu.client.set_host("localhost/api")
gazu.log_in("********@gmail.com", "*********")

Traceback (most recent call last):
File "", line 1, in
File "/home/artem/.local/lib/python2.7/site-packages/gazu/init.py", line 34, in log_in
"auth/login", {"email": email, "password": password}
File "/home/artem/.local/lib/python2.7/site-packages/gazu/client.py", line 161, in post
get_full_url(path), json=data, headers=make_auth_header()
File "/home/artem/.local/lib/python2.7/site-packages/requests/sessions.py", line 581, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "/home/artem/.local/lib/python2.7/site-packages/requests/sessions.py", line 519, in request
prep = self.prepare_request(req)
File "/home/artem/.local/lib/python2.7/site-packages/requests/sessions.py", line 462, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "/home/artem/.local/lib/python2.7/site-packages/requests/models.py", line 313, in prepare
self.prepare_url(url, params)
File "/home/artem/.local/lib/python2.7/site-packages/requests/models.py", line 387, in prepare_url
raise MissingSchema(error)
requests.exceptions.MissingSchema: Invalid URL 'localhost/api/auth/login': No schema supplied. Perhaps you meant http://localhost/api/auth/login?

Python 2, Ubuntu 18.02,
{"api": "Zou", "version": "0.11.48"}

package installation from setup.py

When I install the package via setup.py, the client.py importation failed because of default_client referencing

adding default_client = None when "running in setup mode" should be enough to fix this issue

Special characters with gazu.project.get_project_by_name()

Hello,

I discovered a search problem when using the gazu.project.get_project_by_name() method.
The use of special characters does not cause errors, nor does it return the desired project!

@frankrousseau 's solution is to use the character ASCII code of the character in hexadecial, and it works perfectly (at least with the & character).
Example: & => %26

get_task_status() on tasks created using new_shot() gives error

I have written a comments-function that checks the task_dict for its status to make sure it uses the same status as before.
When I run this on new shots that I have created using gazu.shot.new_shot() I'm getting the error that it can't find task["task_status_id"] inside function get_task_status() in task.py.

It seems like newly created tasks don't have the task_status_id key, thus throwing this error. The key should exist but be empty so if no task status is applied the return would be empty instead of an error.

get_shot_url() and get_asset_url() don't add the episode part to the url

get_shot_url() and get_asset_url() don't add the episode part to the url when working in a TV-Show project.
I'm getting the url:
.../productions/beebe2de-6fb2-43e0-86d4-6c5e519b1866/shots/178e1ab3-16e4-4610-b8f4-027205e3e1b4/
when I should get the url:
.../productions/beebe2de-6fb2-43e0-86d4-6c5e519b1866/episodes/5b5b7a45-a596-4231-aef8-9f25842c9c87/shots/178e1ab3-16e4-4610-b8f4-027205e3e1b4

episode_id not work in new_asset method

Hello,

As said in the title, episode_id is not taken into account (same when using source_id in extra_data).

In the meantime I made a fix by doing a gazu.client.put() to change the value of source_id after its creation!

gazu.shot.new_sequence() cannot be used for a short film

The method is made like thisgazu.shot.new_sequence(project, episode, name).

If I want to create a Sequence for a shot film, gazu.shot.all_episodes_for_project() returns [], then gazu.shot.new_sequence raises an error when called.

get_episode_by_name raises ServerErrorException

The following methods appear to be broken.

gazu.shot.get_episode_by_name
gazu.shot.get_sequence_by_name
gazu.scene.get_scene_by_name
gazu.shot.get_shot_by_name

Error seems to be related to the project.id formatting, but a call to gazu.asset.get_asset_by_name(project, 'Perso1') with the same project will succeed.

Local error

They will fail with a ServerErrorException (here from a pytest run)

_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
python\test\test_explorer.py:25: in default_preferences
    episode = pipeline_client.shot.get_episode_by_name(project, 'e001')
..\gazu\gazu\cache.py:147: in wrapper
    kwargs
..\gazu\gazu\cache.py:66: in insert_value
    returned_value = function(*args, **kwargs)
..\gazu\gazu\shot.py:78: in get_episode_by_name
    episode_name
..\gazu\gazu\client.py:177: in fetch_first
    entries = get(url_path_join('data', path))
..\gazu\gazu\client.py:97: in get
    check_status(response, path)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

request = <Response [500]>
path = 'data/episodes?project_id=9405c0a7-d503-497d-bf16-bd82a5707c22&name=e001'

    def check_status(request, path):
        """
        Raise an exception related to status code, if the status code does not match
        a success code.
        """
        status_code = request.status_code
        if (status_code == 404):
            raise RouteNotFoundException(path)
        elif (status_code == 403):
            raise NotAllowedException(path)
        elif (status_code == 400):
            text = request.json().get("message", "No additional information")
            raise ParameterException(path, text)
        elif (status_code == 405):
            raise MethodNotAllowedException(path)
        elif (status_code in [401, 422]):
            raise NotAuthenticatedException(path)
        elif (status_code in [500, 502]):
            print(request.text)
>           raise ServerErrorException(path)
E           ServerErrorException: data/episodes?project_id=9405c0a7-d503-497d-bf16-bd82a5707c22&name=e001

Server Error

gunicorn error log on the server side :

[2018-12-28 12:53:57 +0000] [30859] [ERROR] Error handling request //data/episodes?project_id=9405c0a7-d503-497d-bf16-bd82a5707c22&name=e001
Traceback (most recent call last):
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/gunicorn/workers/base_async.py", line 56, in handle
    self.handle_request(listener_name, req, client, addr)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/gunicorn/workers/ggevent.py", line 160, in handle_request
    addr)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/gunicorn/workers/base_async.py", line 107, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask/app.py", line 1997, in __call__
    return self.wsgi_app(environ, start_response)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_socketio/__init__.py", line 43, in __call__
    start_response)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/engineio/middleware.py", line 49, in __call__
    return self.wsgi_app(environ, start_response)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask/app.py", line 1985, in wsgi_app
    response = self.handle_exception(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask/app.py", line 1540, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 268, in error_router
    return self.handle_error(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask/app.py", line 1614, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 271, in error_router
    return original_handler(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask/app.py", line 1517, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 268, in error_router
    return self.handle_error(e)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask/app.py", line 1612, in full_dispatch_request
    rv = self.dispatch_request()
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask/app.py", line 1598, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 477, in wrapper
    resp = resource(*args, **kwargs)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask/views.py", line 84, in view
    return self.dispatch_request(*args, **kwargs)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_restful/__init__.py", line 587, in dispatch_request
    resp = meth(*args, **kwargs)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/flask_jwt_extended/view_decorators.py", line 38, in wrapper
    return fn(*args, **kwargs)
  File "/opt/zou/zou/app/blueprints/shots/resources.py", line 326, in get
    user_service.check_project_access(criterions)
  File "/opt/zou/zou/app/services/user_service.py", line 308, in check_project_access
    check_belong_to_project(project_id)
  File "/opt/zou/zou/app/services/user_service.py", line 294, in check_belong_to_project
    project = projects_service.get_project(project_id)
  File "/opt/zou/zou/app/services/projects_service.py", line 154, in get_project
    return get_project_raw(project_id).serialize()
  File "/opt/zou/zou/app/services/projects_service.py", line 139, in get_project_raw
    project = Project.get(project_id)
  File "/opt/zou/zou/app/models/base.py", line 42, in get
    return cls.query.get(id)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 871, in get
    ident, loading.load_on_ident)
  File "/opt/zou/virtualenv/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 886, in _get_impl
    ','.join("'%s'" % c for c in mapper.primary_key))
InvalidRequestError: Incorrect number of values in identifier to formulate primary key for query.get(); primary key columns are 'project.id'

<Revision> semble être hardcodé pour `folder_path`

J'ai simplifié ce file tree pour l'exemple:

PROJECT_FILE_TREE = {
  "preview": {
    "mountpoint": "D:",
    "root": "productions",
    "folder_path": {
        "shot": "<Project>/p<Shot>/<TaskType>/v<Revision>",
    ...
    },
    "file_name": {
        "shot": "<Episode>_s<Sequence>_p<Shot>_<TaskType>_v<Revision>",
        ...
    }
  },
}

Le pattern <Revision> ou <Version> fonctionne très bien sur le file_name mais lorsqu'il est utilisé pour le folder_path il va toujours renvoyer 001 même si la version est supérieure.

delete_project(): Doesn't delete the project

My project has be created with the demo script and I unliked everything after.

Running:
project = gazu.project.get_project_by_name('Caminandes_old') gazu.project.remove_project(project, True)

I get:

File "/Users/user/Documents/Logiciels/Stax/TestGazu/delete_production.py", line 7, in
gazu.project.remove_project(project, True)
File "/Users/user/Documents/Logiciels/Stax/TestGazu/venv/lib/python3.6/site-packages/gazu/project.py", line 89, in remove_project
return client.delete(path)
File "/Users/user/Documents/Logiciels/Stax/TestGazu/venv/lib/python3.6/site-packages/gazu/client.py", line 190, in delete
check_status(response, path)
File "/Users/user/Documents/Logiciels/Stax/TestGazu/venv/lib/python3.6/site-packages/gazu/client.py", line 221, in check_status
raise ParameterException(path, text)
gazu.exception.ParameterException: ('data/projects/adb96f9a-4bad-4e22-8f7c-e37192c015bf?force=true', 'No additional information')

Trying to update task-assignees: "AttributeError: 'str' object has no attribute '_sa_instance_state'"

Hello everyone, I'm trying to update task-data using gazu.
I'm using the command:
gazu.task.client.put("data/tasks/%s" % task_id, data_dict)
which works fine with all data except when it comes to the 'assignees', whose id-codes are represented in a list.
Zou then throws an error:


Server stacktrace:
Traceback (most recent call last):
  File "/opt/zou/zouenv/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request                    
    rv = self.dispatch_request()
  File "/opt/zou/zouenv/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request                         
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/opt/zou/zouenv/lib/python3.6/site-packages/flask_restful/__init__.py", line 477, in wrapper                      
    resp = resource(*args, **kwargs)
  File "/opt/zou/zouenv/lib/python3.6/site-packages/flask/views.py", line 84, in view                                     
    return self.dispatch_request(*args, **kwargs)
  File "/opt/zou/zouenv/lib/python3.6/site-packages/flask_restful/__init__.py", line 587, in dispatch_request             
    resp = meth(*args, **kwargs)
  File "/opt/zou/zouenv/lib/python3.6/site-packages/flask_jwt_extended/view_decorators.py", line 38, in wrapper           
    return fn(*args, **kwargs)
  File "/opt/zou/zouenv/lib/python3.6/site-packages/zou/app/blueprints/crud/base.py", line 262, in put                    
    instance.update(data)
  File "/opt/zou/zouenv/lib/python3.6/site-packages/zou/app/models/base.py", line 153, in update                          
    setattr(self, key, value)
  File "/opt/zou/zouenv/lib/python3.6/site-packages/sqlalchemy/orm/attributes.py", line 229, in __set__                   
    instance_dict(instance), value, None)
  File "/opt/zou/zouenv/lib/python3.6/site-packages/sqlalchemy/orm/attributes.py", line 1105, in set                      
    initiator=evt)
  File "/opt/zou/zouenv/lib/python3.6/site-packages/sqlalchemy/orm/collections.py", line 762, in bulk_replace             
    appender(member, _sa_initiator=initiator)
  File "/opt/zou/zouenv/lib/python3.6/site-packages/sqlalchemy/orm/collections.py", line 1044, in append                  
    item = __set(self, item, _sa_initiator)
  File "/opt/zou/zouenv/lib/python3.6/site-packages/sqlalchemy/orm/collections.py", line 1016, in __set                   
    item = executor.fire_append_event(item, _sa_initiator)
  File "/opt/zou/zouenv/lib/python3.6/site-packages/sqlalchemy/orm/collections.py", line 680, in fire_append_event        
    item, initiator)
  File "/opt/zou/zouenv/lib/python3.6/site-packages/sqlalchemy/orm/attributes.py", line 970, in fire_append_event         
    initiator or self._append_token or self._init_append_token())
  File "/opt/zou/zouenv/lib/python3.6/site-packages/sqlalchemy/orm/unitofwork.py", line 43, in append                     
    item_state = attributes.instance_state(item)
AttributeError: 'str' object has no attribute '_sa_instance_state'

Error message:
'str' object has no attribute '_sa_instance_state'

Googling the issue I found somewhere that it expects a map-object. But replacing the list with
map(lambda x:x, ["<Person-id>"]) doesn't work because json cannot interpret that.

Is there a solution?

all tasks for person vs done tasks

Hi ...

Not sure if this is correct, but the request seems the same for both all_tasks_for_person and all_done_tasks_for_person ...

task.py, line 206 - 223

`@cache
def all_tasks_for_person(person):
"""
Returns:
list: Tasks that are not done for given person (only for open projects).
"""
person = normalize_model_parameter(person)
return client.fetch_all("persons/%s/tasks" % person["id"])

@cache
def all_done_tasks_for_person(person):
"""
Returns:
list: Tasks that are done for given person (only for open projects).
"""
person = normalize_model_parameter(person)
return client.fetch_all("persons/%s/tasks" % person["id"])
`

I think the all_done_tasks_for_person needs to call something else ?

'data' from handler is not consistent with gazu.task.get_task()'s requirement

With the handler, for a task:update, I get a data dict with only one key:
{'task_id': 'f094fdff-5fc9-417a-817c-86573904947d'}

gazu.task.get_task() requires a dict with a 'id' key.

I have to hack to make it work:

task =  {'id': data.get('task_id')}
current_task = gazu.task.get_task(task)

If I pass the data object without anything, I get a key missing error.

PS: I used a daemon handler for this test.

Simplify gazu.task.set_main_preview arguments

Problem

The gazu.task.set_main_preview methods takes two arguments asset and preview_file
As discussed on slack this

  • is unnecessarily verbose as the asset can actually be inferred from preview_file->task->entity.
  • might cause weird situations such as using a preview on an unrelated asset.

Proposed solution

We could refactor gazu.task.set_main_preview to take only preview_file as an argument.

Cannot delete asset

If I get an asset, I can not delete it with current gazu commands, it rises a RouteNotFoundException.

> a = gazu.asset.get_asset_by_name({'id':"7896a9aa-dd4b-4abb-93a5-d96bd9828c7f"}, 'Ag10_baguette')
> print(a)
{u'entity_type_id': u'ff94db8f-2345-465e-8561-22dc24c2fd10', u'description': u'', u'parent_id': None, u'preview_file_id': None, u'entities_out': [], u'created_at': u'2017-12-12T13:35:09.779624', u'shotgun_id': None, u'updated_at': u'2017-12-12T13:35:09.779633', u'canceled': False, u'type': u'Entity', u'entities_in': [], u'project_id': u'7896a9aa-dd4b-4abb-93a5-d96bd9828c7f', u'data': None, u'id': u'02835ad0-158a-41df-b836-f7570aae2c07', u'name': u'Ag10_baguette'}

> gazu.asset.remove_asset(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/u/lodeve-kitsu-webservices/gazu/gazu/asset.py", line 99, in remove_asset
    asset["id"]
  File "/u/lodeve-kitsu-webservices/gazu/gazu/client.py", line 145, in delete
    check_status(response.status_code, path)
  File "/u/lodeve-kitsu-webservices/gazu/gazu/client.py", line 155, in check_status
    raise RouteNotFoundException(path)
gazu.exception.RouteNotFoundException: data/projects/7896a9aa-dd4b-4abb-93a5-d96bd9828c7f/asset-types/ff94db8f-2345-465e-8561-22dc24c2fd10/assets/02835ad0-158a-41df-b836-f7570aae2c07

gazu.task.add_preview doesn't error when upload fails

Issue

It seems that gazu.task.add_preview silently fails when it failed to upload and attach a preview to the comment. Additionally it does not return the result that helps to identify whether the upload succeeded. As such, it appears as if the upload succeeded but it doesn't show it online.

This seems to be due to the fact that it does return the result from the client.post but ignores any return information from client.upload which does identify that the upload fails.

The error I got from the client.upload (when printing that inside the function) in this case was:

{u'message': u'Normalization failed.'}

More context when requesting a shot or an asset ?

When getting a specific shot information using :
get_shot({'id':'98685e03-e787-4fa5-9be1-840a2cc88cff'})

We get useful information such as :

u'created_at': u'2017-11-23T14:45:02.569117',
u'data': {},
u'description': None,
u'entities_in': [],
u'entities_out': [u'28fd5ee2-8d4f-439d-804f-4c0110d3248e',
                  u'8093f0e7-cb45-464c-a709-a88e3a10f04b'],
u'entity_type_id': u'41f39774-d77d-4428-8124-625cd2acb86f',
u'id': u'98685e03-e787-4fa5-9be1-840a2cc88cff',
u'name': u'P004',
u'parent_id': u'13280382-cfe4-4c12-a367-e831fa760e18',
u'preview_file_id': u'479633bf-0905-4905-9906-77596cd03694',
u'project_id': u'7896a9aa-dd4b-4abb-93a5-d96bd9828c7f',
u'shotgun_id': None,
u'type': u'Entity',
u'updated_at': u'2017-11-23T16:59:20.191010'}

But the name (P004) is not enough to contextualize the shot for the user. What is its sequence, episode or projet ? What if I've 10 episodes, with 10 sequences and all of them have a shot P0004 ?

To get the full context, I need to do 3 more requests :

  • one for the projet name (the id is provided)
  • one for the sequence name (probably parent_id ?)
  • one for the episode name (probably the parent_id/parent_id ?)

should that information be provided as default information ? Or at least as ids (episode_id and sequence_id) ? As shots are always (?) defined by their parent : sequence/episode/project. And I'm thinking of the same for assets.

Does it add too much internal load during basic requests ?

Event Types

Hi,

I've been writing some utilities to update/sync Avalon based on listening to events using Gazu, however the event types I've been able to find seem to be a bit inconsistent and/or missing.

These are the events I've been able to work out so far:

Gazu Event Types:

Gazu Event Types:

Assets:
    New:        entity:new
    Update:     N/A
    Delete:     asset:delete

Shots:
    New:        shot:new
    Update:     N/A
    Delete:     shot:delete

Sequences:
    New:        sequence:new
    Update:     N/A
    Delete:     entity:delete

Tasks:
    New:        task:new
    Update:     task:update

Episode:
    New:        episode:new
    Update:     N/A
    Delete:     entity:delete

Projects:
    New:        project:new
    Update:     project:update
    Delete:     project:delete

Comment:
    New:        comment:new
    Update:     N/A
    Delete:     comment:delete

Preview:
    Set:        preview-file:set-main
    New:        preview-file:add-file

The docs say that there should be a new, update and delete event type for at least models/assets, however the update event type seems to missing (from just about everything).

Also both Episode and Sequence delete share the same entity:delete event type, so you can't tell which was deleted.

Would it be possible to get at least an asset update event? This would at least allow for consistent asset names between the two systems.

Thanks,
Cameron

Installing zou on windows

Hi

Installing zou on windows gives an error related to Uwsgi , the error is about os.uname.
I noticed the installation for Linux, is installing on windows is possible?

Thanks

delete_comment(): Not existing function

Hi,
I'd like to be able to handle a project only with the API, I can add_comment but I cannot remove/delete any this way.
It'd be very useful to have a gazu.task.delete_comment(my_comment) / gazu.task.remove_comment(my_comment) function.

Data is not saved when creating an entity

When creating a shot for example, my dict data is not save in the database

data={'frame_in':1, 'frame_out':25}
shot = gazu.client.post("/data/projects/%s/shots"% project['id'], {'name':"shotName", 'sequence_id':sequence['id'], 'data':data})

the current workaround is, just after doing the gazu.client.post, making a new update query with the newly created shot :

data={'frame_in':1, 'frame_out':25}
shot = gazu.client.post("/data/projects/%s/shots"% project['id'], {'name':"shotName", 'sequence_id':sequence['id'], 'data':data})
gazu.client.put("data/entities/%s"% shot['id'], {'data':data})

gazu.task.all_tasks_for_episode() doesn't work

project = gazu.project.get_project_by_name('Caminandes')

episodes = gazu.shot.all_episodes_for_project(project)
tasks = gazu.task.all_tasks_for_episode(episodes[0])

print(tasks)

-->
[]

Errors all_task_types_for_episode()/all_task_types_for_sequence()

Hello,

I need to get all tasks types from an episode, but, gazu.task.all_task_types_for_episode() return an empty list.

Code example:

project = gazu.project.get_project_by_name('my_project_name')
episode = gazu.shot.get_episode_by_name(project, 'my_episode_name')
tasks_types = gazu.task.all_task_types_for_episode(episode)

Same with gazu.task.all_task_types_for_sequence()
I have to do something like this to make it work

project = gazu.project.get_project_by_name('my_project_name')
episode = gazu.shot.get_episode_by_name(project, 'my_episode_name')
sequences = gazu.shot.all_sequences_for_episode(episode)
shots = gazu.shot.all_shots_for_sequence(sequences[0])
tasks_types = gazu.task.all_task_types_for_shot(shots[0])

Have a nice day!

"Scene" - what is it?

In kitsu-web I can create the episodes, the sequences, and shots.
In gazu
What does "Scene" mean in Gazu?

"sequences" is the rendering result?

Method to restore a shot

Hi,

I saw in the web interface that we could restore a deleted shot but I can't manage to find a method in gazu to do the same thing.

Is it an oversight ? Or am i missing something here ?

Thank you

gazu.task.get_task_by_name() fails for role Supervisor and lower

Issue

When using gazu.task.get_task_by_name it works fine when logged in as the Studio Manager, but it fails when logged in as a Supervisor or CG Artist even though it's on a project they are assigned to and online they are capable of seeing exactly that resulting task. As such, online they are allowed to see it but are declined authentication through gazu.

Error message
# gazu.exception.NotAllowedException: data/tasks?name=main&entity_id={entity_id}&task_type_id={task_type_id}
# Traceback (most recent call last):
#   File "P:\pipeline\2.1_dev\git\gazu\gazu\task.py", line 205, in get_task_by_name
#     entity_id=entity["id"]
#   File "P:\pipeline\2.1_dev\git\gazu\gazu\client.py", line 250, in fetch_first
#     entries = get(url_path_join('data', path))
#   File "P:\pipeline\2.1_dev\git\gazu\gazu\client.py", line 119, in get
#     check_status(response, path)
#   File "P:\pipeline\2.1_dev\git\gazu\gazu\client.py", line 198, in check_status
#     raise NotAllowedException(path)
# gazu.exception.NotAllowedException: data/tasks?name=main&entity_id={entity_id}&task_type_id={task_type_id}

Not sure if it would've been a security issue, but I renamed the ids to {entity_id} and {task_type_id} - if you were wondering why it looked like that.

Workaround

Is there a workaround?

In the documentation I noticed just now this function is deprecated, however I'm clueless as to how I would otherwise get the task for an asset. I noticed there is all_tasks_for_entity_and_task_type, but how could a single task have the same task type more than once? :) Is that what the "main" differentiator was for?

Get notifications : ServerError

Hi
We have a server error when retrieving user notifications.
Only one kitsu person have this problem. It's maybe due to a big number of notifications (+16000).

Here's the traceback :

A server error occured!Server stacktrace:
Traceback (most recent call last):
  File "/opt/zou/zouenv/lib/python3.5/site-packages/flask/app.py", line 1949, in full_dispatch_request
    rv = self.dispatch_request()
  File "/opt/zou/zouenv/lib/python3.5/site-packages/flask/app.py", line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/opt/zou/zouenv/lib/python3.5/site-packages/flask_restful/__init__.py", line 468, in wrapper
    resp = resource(*args, **kwargs)
  File "/opt/zou/zouenv/lib/python3.5/site-packages/flask/views.py", line 89, in view
    return self.dispatch_request(*args, **kwargs)
  File "/opt/zou/zouenv/lib/python3.5/site-packages/flask_restful/__init__.py", line 583, in dispatch_request
    resp = meth(*args, **kwargs)
  File "/opt/zou/zouenv/lib/python3.5/site-packages/flask_jwt_extended/view_decorators.py", line 103, in wrapper
    return fn(*args, **kwargs)
  File "/opt/zou/zouenv/lib/python3.5/site-packages/zou/app/blueprints/crud/base.py", line 296, in put
    instance = self.get_model_or_404(instance_id)
  File "/opt/zou/zouenv/lib/python3.5/site-packages/zou/app/blueprints/crud/base.py", line 220, in get_model_or_404
    instance = self.model.get(instance_id)
  File "/opt/zou/zouenv/lib/python3.5/site-packages/zou/app/models/base.py", line 40, in get
    return cls.query.get(id)
  File "/opt/zou/zouenv/lib/python3.5/site-packages/sqlalchemy/orm/query.py", line 1018, in get
    return self._get_impl(ident, loading.load_on_pk_identity)
  File "/opt/zou/zouenv/lib/python3.5/site-packages/sqlalchemy/orm/query.py", line 1135, in _get_impl
    return db_load_fn(self, primary_key_identity)
  File "/opt/zou/zouenv/lib/python3.5/site-packages/sqlalchemy/orm/loading.py", line 286, in load_on_pk_identity
    return q.one()
  File "/opt/zou/zouenv/lib/python3.5/site-packages/sqlalchemy/orm/query.py", line 3490, in one
    ret = self.one_or_none()
  File "/opt/zou/zouenv/lib/python3.5/site-packages/sqlalchemy/orm/query.py", line 3459, in one_or_none
    ret = list(self)
  File "/opt/zou/zouenv/lib/python3.5/site-packages/sqlalchemy/orm/loading.py", line 100, in instances
    cursor.close()
  File "/opt/zou/zouenv/lib/python3.5/site-packages/sqlalchemy/util/langhelpers.py", line 70, in __exit__
    with_traceback=exc_tb,
  File "/opt/zou/zouenv/lib/python3.5/site-packages/sqlalchemy/util/compat.py", line 182, in raise_
    raise exception
  File "/opt/zou/zouenv/lib/python3.5/site-packages/sqlalchemy/orm/loading.py", line 80, in instances
    rows = [proc(row) for row in fetch]
  File "/opt/zou/zouenv/lib/python3.5/site-packages/sqlalchemy/orm/loading.py", line 80, in <listcomp>
    rows = [proc(row) for row in fetch]
  File "/opt/zou/zouenv/lib/python3.5/site-packages/sqlalchemy/orm/loading.py", line 588, in _instance
    populators,
  File "/opt/zou/zouenv/lib/python3.5/site-packages/sqlalchemy/orm/loading.py", line 725, in _populate_full
    dict_[key] = getter(row)
  File "/opt/zou/zouenv/lib/python3.5/site-packages/sqlalchemy/sql/type_api.py", line 1283, in process
    return process_value(value, dialect)
  File "/opt/zou/zouenv/lib/python3.5/site-packages/sqlalchemy_utils/types/choice.py", line 172, in process_result_value
    return self.type_impl.process_result_value(value, dialect)
  File "/opt/zou/zouenv/lib/python3.5/site-packages/sqlalchemy_utils/types/choice.py", line 199, in process_result_value
    return Choice(value, self.choices_dict[value])
KeyError: 'Notification'Error message:
'Notification'---------------------------------------------------------------------------
ServerErrorException                      Traceback (most recent call last)
<ipython-input-44-6f749ab382c2> in <module>
      2     n.update(read=True)
      3     print(n)
----> 4     gazu.client.put(f'/data/notifications/{n.get("id")}', n)
      5     break
      6 /srv/dev/prod/gazu/gazu/client.py in put(path, data, client)
    225         headers=make_auth_header(client=client)
    226     )
--> 227     check_status(response, path)
    228     return response.json()
    229 /srv/dev/prod/gazu/gazu/client.py in check_status(request, path)
    296         except:
    297             print(request.text)
--> 298         raise ServerErrorException(path)
    299     return status_code
    300 ServerErrorException: /data/notifications/8c3e0242-29d1-4167-aae1-02d478ee0dd0

Fonction de tri par projet manquante

Il y a des fonctions existantes qui permettent de filtrer les données par projet, mais il y en a une particulière qui manque.

Celle-ci existe: gazu.asset.all_asset_types_for_project(project, client=<gazu.client.KitsuClient object>)
Celle-ci serait pratique: gazu.task.all_task_types_for_project(project, client=<gazu.client.KitsuClient object>)

Il est possible de récupérer les IDs de ceux-ci directement dans l'objet du projet, mais ce n'est pas pratique.
De plus, la fonction gazu.task.get_task_type n'est pas présente dans la documentation.

HTTP(HTML) errors with gazu.client.upload

Hello,

I had problems uploading videos, an error appeared, but no details on it since it is the one that interprets the JSON that causes problem.

By modifying the gazu.client.upload function, I managed to get the http 413 error (sent in HTML format via NGinx).
So, would it be possible to add an exception that would return these errors, to easily fix these problems?

I think it's not necessary to say it, but you never know. I use the gazu.task.add_preview function to send this.

Image format when downloading

Hello,

We try to put posted images in our pipeline.
We use the gazu.client.download(url, download_path) function.

Problem is

  • .png file was uploaded
  • .png file is downloaded
  • .png file is not readable in Photoshop (or Qt based applications) unless you rename the file to .jpg

Maybe re-encoding is happening at some point ?

Thanks

gazu.task.all_task_statuses

Hello,

While using Gazu, I realized a lack that forced me to have hard data in the code.

I would like to recover the TaskStatuses but since the documentation, I find only that concerning TaskTypes ...

If you have a solution to list all the statuses, can you tell me how to proceed?

Otherwise it would be convenient to have a dedicated function for this purpose gazu.task.all_task_statuses.

update_sequence_data : get() takes no keyword arguments

Gazu : 0.8.0
Kitsu : 0.12.1
Zou : 0.12.1

When using gazu.shots.update_sequence_data, a raise appears :

File: gazu/gazu/shot.py", line 378, in update_sequence_data
    if not current_sequence.get('data', client=default):
TypeError : get() takes no keyword arguments

What is name="main" in a task query ?

If I query a precise task like

task = gazu.client.get("data/tasks/323f103e-e440-453c-9d94-370ef534f973")

I've a name key, but it's value is "main" no matter if it's a shot or an asset task.
Why is it not the name of the task ? Like "Layout" or "Modeling" ?

We've to now query the task_types using the task_type_id key of the task object to know which task we are talking about.
Maybe as issue #12 (context for shots and assets) , tasks can have some more quick context, like

task['name']   #   Anim-Main, Anim-Crowd, ...
task['department'] # Animation
task['department_id']  
task['status']   #   WFA, ... # Not only status_id ?

Asset name is capitalized when created

When creating an asset, its name is capitalized no matter how it was provided.

a = gazu.asset.new_asset(project={'id':project_id}, asset_type={'id':lib_types[t]}, name="MyAwesomeNameXXX", description="")

will be created as "Myawesomenamexxx"

I ve to then do something like :

name = "MyAwesomeNameXXX"
# Add my asset
a = gazu.asset.new_asset(project={'id':project_id}, asset_type={'id':lib_types[t]}, name=name, description="")
# Update the name of the created asset...
gazu.client.put("data/entities/%s"% a['id'], {'name':name})

The last line is because I've found yet the gazu.asset.update() command or something. I'll add it later.

add_preview(): Upload works but script crashes

Based on https://github.com/cgwire/cgwire-demo script.

Using preview_file = gazu.task.add_preview( task_sb, comment, file_paths_sb[index] ) to upload a '.mp4' file (works as expected with a '.png') uploads the file, I'm able to see the revision on the task, but rises the following error:

File "demo.py", line 365, in
file_paths_sb[index]
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/gazu/task.py", line 573, in add_preview
client.upload(path, preview_file_path)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/gazu/client.py", line 313, in upload
url, headers=make_auth_header(), files=files
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/requests/models.py", line 897, in json
return complexjson.loads(self.text, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/init.py", line 354, in loads
return _default_decoder.decode(s)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/decoder.py", line 339, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/decoder.py", line 357, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

Lead:

I get a 504 Gateway Time-out from nginx.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.