<commit_before>



# An API client for the VersionOne agile project management system.


## Overview

### Dynamic reflection of all V1 asset types:

  Just instantiate a V1Meta.  All asset types defined on the server are available
  as attributes on the instance.  The metadata is only loaded once, so you must
  create a new instance of V1Meta to pick up metadata changes.


### Simple access to individual assets:

  Assets are created on demand and cached so that once instance always represents
  the same asset.  


### Lazyily loaded values and relations:

  Asset instances are created with any data available, and query the server on-demand
  for attributes that aren't currently fetched. 


### Simple query syntax:

      for s in v1.Story.where(Name='Add feature X to main product"):
          print s.Name, s.CreateDate, [o.name for o in s.Owners]


### Simple creation syntax:

      new_story = v1.Story.create(Name='New Story', scope=v1.Scope(1002))


### Simple update syntax:

      story = v1.Story(1005)
      story.Name = 'Super Cool Feature Redux'
      story.Owners = list( v1.Members.where(Name='<NAME>') )
      
      v1.commit()  # flushes all pending updates to the server


## TODO

  * Make things Moment-aware
  
  * Convert types between client and server (right now everything is a string)
  
  * Add debug logging
  
  * Beef up test coverage
  
    * Need to mock up server
    
  * Examples
  <commit_msg>improve readme<commit_after>



# An API client for the VersionOne agile project management system.


## Overview

### Dynamic reflection of all V1 asset types:

  Just instantiate a V1Meta.  All asset types defined on the server are available
  as attributes on the instance.  The metadata is only loaded once, so you must
  create a new instance of V1Meta to pick up metadata changes.
  
      from v1pysdk import V1Meta
      
      v1 = V1Meta()  # Assumes localhost/VersionOne.Web, credentials Admin/Admin
      
      v1 = V1Meta(
             address = 'v1server.mycompany.com',
             instance = 'VersionOne',
             username = 'jsmith',
             password = 'swordfish'
             )


### Simple access to individual assets:

  Assets are created on demand and cached so that once instance always represents
  the same asset.

      s = v1.Story(1005)
      
      print s is v1.Story(1005)   # True
      


### Lazyily loaded values and relations:

  Asset instances are created with any data available, and query the server on-demand
  for attributes that aren't currently fetched. 


### Simple query syntax:

      for s in v1.Story.where(Name='Add feature X to main product"):
          print s.Name, s.CreateDate, [o.name for o in s.Owners]


### Simple creation syntax:

      new_story = v1.Story.create(Name='New Story', scope=v1.Scope(1002))
      # creation happens immediately. No need to commit.
      print new_story


### Simple update syntax:

      story = v1.Story(1005)
      story.Name = 'Super Cool Feature Redux'
      story.Owners = list( v1.Members.where(Name='<NAME>') )
      
      v1.commit()  # flushes all pending updates to the server


## TODO

  * Make things Moment-aware
  
  * Convert types between client and server (right now everything is a string)
  
  * Add debug logging
  
  * Beef up test coverage
  
    * Need to mock up server
    
  * Examples
  
{'fraction_non_alphanumeric': 0.07408509372210652, 'fraction_numerical': 0.01517405534067242, 'mean_word_length': 2.7108167770419427, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6656578', 'n_tokens_mistral': 1007, 'n_tokens_neox': 930, 'n_words': 395}